Chapters ▾ 2nd Edition

10.8 (Git Internals) - متغیرهای محیطی (Environment Variables)

متغیرهای محیطی (Environment Variables)

گیت همیشه داخل یک شل bash اجرا می‌شود و از تعدادی متغیر محیطی شل استفاده می‌کند تا رفتار خود را تعیین کند. گاهی اوقات دانستن این متغیرها و اینکه چگونه می‌توان از آن‌ها برای کنترل رفتار گیت استفاده کرد، بسیار مفید است. این فهرست شامل تمام متغیرهای محیطی‌ای که گیت به آن‌ها توجه می‌کند نیست، اما ما مفیدترین آن‌ها را بررسی خواهیم کرد.

رفتار سراسری (Global Behavior)

برخی از رفتارهای کلی گیت به عنوان یک برنامهٔ کامپیوتری، به متغیرهای محیطی وابسته است.

GIT_EXEC_PATH مشخص می‌کند که Git برای یافتن زیر-برنامه‌های خودش (مثل git-commit، git-diff و سایر ابزارها) کجا را بررسی کند. برای مشاهده تنظیم فعلی می‌توانید دستور git --exec-path را اجرا کنید.

HOME معمولاً قابل شخصی‌سازی در نظر گرفته نمی‌شود (چون بخش‌های زیادی به آن وابسته‌اند)، اما این همان جایی است که Git به دنبال فایل تنظیمات global می‌گردد. اگر می‌خواهید یک نصب Git کاملاً قابل حمل (portable) داشته باشید، به همراه تنظیمات global، می‌توانید مقدار HOME را در shell profile نسخه‌ی portable Git تغییر دهید.

PREFIX مشابه است، اما برای تنظیمات سیستمی استفاده می‌شود. Git این فایل را در مسیر $PREFIX/etc/gitconfig جستجو می‌کند.

GIT_CONFIG_NOSYSTEM اگر تنظیم شود، استفاده از فایل تنظیمات سیستمی را غیرفعال می‌کند. این زمانی مفید است که تنظیمات سیستمی باعث تداخل در دستورات شما شوند، اما شما دسترسی به تغییر یا حذف آن‌ها نداشته باشید.

GIT_PAGER برنامه‌ای را کنترل می‌کند که برای نمایش خروجی چندصفحه‌ای در خط فرمان استفاده می‌شود. اگر تنظیم نشده باشد، به عنوان جایگزین از PAGER استفاده می‌شود.

GIT_EDITOR ویرایشگری است که Git در مواقعی که کاربر نیاز به نوشتن یا ویرایش متن دارد (برای مثال یک پیام commit) اجرا می‌کند. اگر این مقدار تنظیم نشده باشد، از EDITOR استفاده خواهد شد.

مکان‌های مخزن (Repository Locations)

گیت از چندین متغیر محیطی استفاده می‌کند تا مشخص کند چگونه با مخزنٔ فعلی تعامل داشته باشد.

GIT_DIR محل قرارگیری پوشه‌ی .git است. اگر این مقدار مشخص نشده باشد، Git در درخت دایرکتوری به سمت بالا حرکت می‌کند تا به ~ یا / برسد و در هر مرحله به دنبال یک پوشه‌ی .git می‌گردد.

GIT_CEILING_DIRECTORIES رفتار جستجو برای پوشه‌ی .git را کنترل می‌کند. اگر به دایرکتوری‌هایی دسترسی دارید که بارگذاری آن‌ها کند است (مثل دایرکتوری روی tape drive یا یک اتصال شبکه کند)، می‌توانید کاری کنید که Git زودتر از جستجو دست بکشد، مخصوصاً اگر Git هنگام ساختن shell prompt فراخوانی شود.

GIT_WORK_TREE محل ریشه‌ی دایرکتوری کاری (working directory) برای یک مخزن غیر-bare است. اگر --git-dir یا GIT_DIR مشخص شده باشد ولی هیچ‌کدام از --work-tree، GIT_WORK_TREE یا core.worktree تنظیم نشده باشند، دایرکتوری کاری فعلی به‌عنوان سطح بالای working tree در نظر گرفته می‌شود.

GIT_INDEX_FILE مسیر فایل ایندکس (فقط در مخازن غیر-bare) را مشخص می‌کند.

GIT_OBJECT_DIRECTORY می‌تواند برای تعیین محل دایرکتوری‌ای استفاده شود که معمولاً در .git/objects قرار دارد.

GIT_ALTERNATE_OBJECT_DIRECTORIES یک لیست جدا شده با colon است (مثل /dir/one:/dir/two:…) که به Git می‌گوید اگر آبجکت‌ها در GIT_OBJECT_DIRECTORY پیدا نشدند، کجا آن‌ها را بررسی کند. اگر پروژه‌های زیادی دارید که شامل فایل‌های بزرگ با محتوای یکسان هستند، این متغیر می‌تواند از ذخیره‌سازی چندین نسخه‌ی تکراری جلوگیری کند.

مسیرهای مشخص (Pathspecs)

“pathspec” به نحوهٔ مشخص کردن مسیرها در گیت اشاره دارد، از جمله استفاده از کاراکترهای جایگزین (wildcards). این مسیرها در فایل .gitignore استفاده می‌شوند، اما همچنین در خط فرمان نیز کاربرد دارند (مثلاً git add *.c).

GIT_GLOB_PATHSPECS و GIT_NOGLOB_PATHSPECS رفتار پیش‌فرض wildcardها را در pathspecها کنترل می‌کنند. اگر مقدار GIT_GLOB_PATHSPECS برابر 1 باشد، کاراکترهای wildcard به‌صورت wildcard عمل می‌کنند (که حالت پیش‌فرض است). اگر مقدار GIT_NOGLOB_PATHSPECS برابر 1 باشد، کاراکترهای wildcard فقط خودشـان را match می‌کنند؛ یعنی چیزی مثل *.c فقط فایلی با نام دقیق “\*.c” را match می‌کند، نه هر فایلی که پسوند .c دارد. می‌توانید این رفتار را در موارد خاص با پیشوند :(glob) یا :(literal) تغییر دهید؛ مثلاً: :(glob)\*.c.

GIT_LITERAL_PATHSPECS هر دو رفتار بالا را غیرفعال می‌کند؛ هیچ کاراکتر wildcardی کار نخواهد کرد و پیشوندهای override هم غیرفعال می‌شوند.

GIT_ICASE_PATHSPECS باعث می‌شود همه‌ی pathspecها به‌صورت case-insensitive عمل کنند.

کامیت کردن (Committing)

ایجاد نهایی یک شیء کامیت در گیت معمولاً توسط git-commit-tree انجام می‌شود، که این متغیرهای محیطی را به‌عنوان منبع اصلی اطلاعات خود استفاده می‌کند و تنها در صورتی به مقادیر تنظیمات پیکربندی رجوع می‌کند که این متغیرها موجود نباشند.

GIT_AUTHOR_NAME نام قابل‌خواندن (human-readable) برای فیلد “author” است.

GIT_AUTHOR_EMAIL ایمیل مربوط به فیلد “author” است.

GIT_AUTHOR_DATE زمان (timestamp) استفاده‌شده در فیلد “author” است.

GIT_COMMITTER_NAME نام قابل‌خواندن (human name) برای فیلد “committer” را تنظیم می‌کند.

GIT_COMMITTER_EMAIL ایمیل مربوط به فیلد “committer” است.

GIT_COMMITTER_DATE برای زمان (timestamp) در فیلد “committer” استفاده می‌شود.

EMAIL ایمیل جایگزین (fallback) است در صورتی که مقدار user.email در تنظیمات مشخص نشده باشد. اگر این هم تنظیم نشده باشد، Git از نام کاربر و نام میزبان (system user و host names) استفاده می‌کند.

شبکه (Networking)

گیت برای انجام عملیات شبکه‌ای از طریق HTTP از کتابخانهٔ curl استفاده می‌کند، بنابراین GIT_CURL_VERBOSE به گیت می‌گوید تمام پیام‌هایی که توسط آن کتابخانه تولید می‌شوند را نمایش دهد. این مشابه اجرای `curl -`v در خط فرمان است.

GIT_SSL_NO_VERIFY به Git می‌گوید که گواهی‌های SSL را بررسی نکند. این مورد گاهی ضروری است، مثلاً زمانی که از یک گواهی self-signed برای ارائه‌ی مخزن‌های Git از طریق HTTPS استفاده می‌کنید، یا وقتی در حال راه‌اندازی یک سرور Git هستید اما هنوز گواهی کامل نصب نشده است.

اگر نرخ انتقال داده در یک عملیات HTTP کمتر از GIT_HTTP_LOW_SPEED_LIMIT بایت بر ثانیه باشد و این وضعیت بیشتر از GIT_HTTP_LOW_SPEED_TIME ثانیه ادامه پیدا کند، Git آن عملیات را متوقف می‌کند. این مقادیر، مقادیر تنظیمات http.lowSpeedLimit و http.lowSpeedTime را override می‌کنند.

GIT_HTTP_USER_AGENT رشته‌ی user-agent را تنظیم می‌کند که Git هنگام برقراری ارتباط از طریق HTTP استفاده می‌کند. مقدار پیش‌فرض چیزی شبیه به git/2.0.0 است.

مقایسه و ادغام (Diffing and Merging)

GIT_DIFF_OPTS یک نام‌گذاری نه‌چندان دقیق (misnomer) است. تنها مقادیر معتبر -u<n> یا --unified=<n> هستند که تعداد خطوط context را در دستور git diff مشخص می‌کنند.

GIT_EXTERNAL_DIFF برای override کردن مقدار تنظیمات diff.external استفاده می‌شود. اگر تنظیم شود، Git هنگام اجرای git diff این برنامه را اجرا خواهد کرد.

GIT_DIFF_PATH_COUNTER و GIT_DIFF_PATH_TOTAL از داخل برنامه‌ای که توسط GIT_EXTERNAL_DIFF یا diff.external مشخص شده، کاربرد دارند. اولی نشان‌دهنده‌ی این است که کدام فایل در یک سری در حال diff شدن است (شروع از 1)، و دومی تعداد کل فایل‌ها در آن batch را مشخص می‌کند.

GIT_MERGE_VERBOSITY خروجی مربوط به recursive merge strategy را کنترل می‌کند. مقادیر مجاز به شکل زیر هستند:

  • 0 هیچ خروجی‌ای ندارد (به‌جز احتمالاً یک پیام خطا).

  • 1 فقط conflictها را نشان می‌دهد.

  • 2 تغییرات فایل‌ها را هم نشان می‌دهد.

  • 3 نشان می‌دهد چه فایل‌هایی به‌دلیل عدم تغییر رد (skip) شدند.

  • 4 همه‌ی مسیرها (paths) را هنگام پردازش نشان می‌دهد.

  • 5 و بالاتر، اطلاعات کامل debugging را نمایش می‌دهند.

مقدار پیش‌فرض برابر با 2 است.

دیباگ کردن (Debugging)

می‌خواهید واقعاً بدانید گیت چه کار می‌کند؟ گیت مجموعه‌ای نسبتاً کامل از ردیابی‌ها (traces) را در خود دارد و تنها کاری که باید انجام دهید، فعال کردن آن‌هاست. مقادیر ممکن برای این متغیرها به شرح زیر هستند:

  • “true”، “1” یا “2” → خروجی trace به stderr نوشته می‌شود.

  • یک مسیر مطلق که با / شروع شود → خروجی trace در آن فایل نوشته خواهد شد.

GIT_TRACE ردیابی‌های عمومی (general traces) را کنترل می‌کند، یعنی مواردی که در هیچ دسته‌بندی خاصی قرار نمی‌گیرند. این شامل گسترش aliasها و واگذاری (delegation) به زیر‌برنامه‌های دیگر می‌شود.

$ 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'

GIT_TRACE_PACK_ACCESS ردیابی مربوط به دسترسی به packfile‌ها را کنترل می‌کند. فیلد اول نام 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

GIT_TRACE_PACKET ردیابی در سطح 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
# […]

GIT_TRACE_PERFORMANCE لاگ‌گیری مربوط به داده‌های 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'

GIT_TRACE_SETUP اطلاعاتی درباره‌ی کشف (discovery) 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

متفرقه (Miscellaneous)

GIT_SSH، در صورتی که مشخص شود، برنامه‌ای است که به جای ssh فراخوانی می‌شود وقتی Git سعی می‌کند به یک هاست SSH متصل شود. این برنامه به شکل زیر فراخوانی می‌شود: $GIT_SSH [username@]host [-p <port>] <command>. توجه داشته باشید که این روش ساده‌ترین راه برای شخصی‌سازی نحوه فراخوانی ssh نیست؛ این روش از پارامترهای اضافی خط فرمان پشتیبانی نمی‌کند. برای پشتیبانی از پارامترهای اضافی خط فرمان، می‌توانید از GIT_SSH_COMMAND استفاده کنید، یک اسکریپت wrapper بنویسید و GIT_SSH را به آن اشاره دهید یا از فایل ~/.ssh/config استفاده کنید.

GIT_SSH_COMMAND فرمان SSH مورد استفاده هنگام تلاش Git برای اتصال به یک هاست SSH را تنظیم می‌کند. این فرمان توسط shell تفسیر می‌شود و می‌توان پارامترهای اضافی خط فرمان را به ssh داد، مانند: GIT_SSH_COMMAND="ssh -i ~/.ssh/my_key" git clone git@example.com:my/repo

GIT_ASKPASS جایگزینی برای مقدار تنظیمات core.askpass است. این برنامه هر بار که Git نیاز به درخواست اطلاعات کاربری از کاربر دارد فراخوانی می‌شود، و می‌تواند یک متن prompt را به عنوان آرگومان خط فرمان دریافت کند و پاسخ را در stdout برگرداند (برای اطلاعات بیشتر در مورد این زیرسیستم، ببینید ذخیره‌سازی اطلاعات ورود (Credential Storage)).

GIT_NAMESPACE دسترسی به refs دارای namespace را کنترل می‌کند و معادل گزینه --namespace است. این مورد عمدتاً در سمت سرور کاربرد دارد، جایی که ممکن است بخواهید چندین fork از یک مخزن را در یک مخزن نگه دارید و تنها refs آنها را جدا نگه دارید.

GIT_FLUSH می‌تواند برای اجبار Git به استفاده از I/O بدون بافر هنگام نوشتن تدریجی به stdout استفاده شود. مقدار 1 باعث می‌شود Git بیشتر flush کند، مقدار 0 باعث می‌شود تمام خروجی بافر شود. مقدار پیش‌فرض (اگر این متغیر تنظیم نشده باشد) انتخاب یک روش بافر مناسب بسته به فعالیت و حالت خروجی است.

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
scroll-to-top