Git
Chapters ▾ 2nd Edition

8.1 Налаштування Git - Конфігурація Git

До цього часу ми розглянули основи роботи Git і як його використовувати, а також ми розповіли про декілька засобів, які надає Git для легшого та ефективнішого його використання. У цьому розділі ми побачимо, як можна змусити Git працювати бажаним чином, запровадивши декілька важливих конфігураційних налаштувань. Із цими засобами легко змусити Git працювати точно так, як потрібно вам, вашій компанії чи групі.

Конфігурація Git

Як ви вже читали в Вступ, можна вказати конфігураційні налаштування Git використовуючи команду git config. Одна з перших речей, що ви зробили — це вказали ваше ім’я та електронну адресу:

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

Тут ви вивчите декілька більш цікавих налаштувань для пристосування Git у такий же самий спосіб.

Спочатку швидке резюме: Git використовує низку конфігураційних файлів для визначення нетипової поведінки, яка вам може знадобитися. Перше місце, куди Git заглядає за цими значеннями, знаходиться у системному файлі /etc/gitconfig, який містить значення, що застосовуються для всіх користувачів системи та всіх їхніх репозиторіїв. Якщо передати опцію --system до git config, то він буде читати і записувати саме в цей файл.

Наступне місце, куди дивиться Git — це файл ~/.gitconfig (або ~/.config/git/config), який є специфічним для кожного користувача. Ви можете змусити Git читати і записувати в цей файл за допомогою опції --global.

Нарешті, Git шукає конфігураційні значення у файлі налаштувань, що розміщений у директорії Git-а (.git/config) будь-якого поточного репозиторія, що ви використовуєте, і відповідають налаштуванням за допомогою опції --local команди git config. Ці значення є специфічними для цього окремого репозиторія. (Якщо не задати явно рівень конфігурацію, типово буде використано цей.)

Кожен з цих “рівнів” (системний, глобальний, локальний) переписує значення попереднього рівня, тобто, наприклад, значення в .git/config перекриває значення в /etc/gitconfig.

Note

Конфігураційні файли Git-а є звичайним текстом, тому ви можете задати ці значення, відредагувавши файл вручну дотримуючись коректного синтаксису. Однак у загальному випадку легше виконати команду git config.

Базові налаштування клієнта

Конфігураційні опції, що розпізнаються Git-ом, належать до двох категорій: клієнтські та серверні. Більшість опцій стосуються сторони клієнта — налаштування ваших персональних робочих вподобань. Існує багато, багато конфігураційних опцій, але велика частка їх корисна лише в певних крайніх випадках; ми розкриємо тут лише найзагальніші та найкорисніші. Щоб побачити список усіх опцій, підтримуваних вашою версією Git, виконайте

$ man git-config

Ця команда виводить список усіх доступних опцій з доволі докладним описом. Також ви можете знайти цю інформацію на http://git-scm.com/docs/git-config.html.

core.editor

За замовчуванням, Git використовує будь-що вказане вами як типовий текстовий редактор у змінних середовища VISUAL чи EDITOR, або повертається до редактора vi, щоб створювати чи вредагувати ваші повідомлення до комітів та теґів. Щоб змінити типові налаштування на щось інше, використовуйте опцію core.editor`:

$ git config --global core.editor emacs

Тепер не важливо, що вказано як типовий редактор для терміналу, Git буде викликати Emacs для редагування повідомлень.

commit.template

Якщо ви вкажете для цього параметра шлях до файла у вашій системі, Git буде використовувати той файл як типове значення для повідомлення при створенні коміту. Власний шаблон для повідомлення коміту може нагадувати вам (або іншим) про правильний формат і стиль таких повідомлень.

Наприклад, розглянемо файл шаблону ~/.gitmessage.txt з таким вмістом:

Subject line (try to keep under 50 characters)

Multi-line description of commit,
feel free to be detailed.

[Ticket: X]

Зверніть увагу на те, що цей шаблон нагадує творцю коміту, що рядок з темою має бути коротким (заради гарного виводу git log --oneline), а також докладніше описати коміт, і послатися на номер задачі, якщо така існує.

Щоб вказати Git, що потрібно використовувати його як типове значення для повідомлення, яке з’являтиметься в редакторі після виконання команди git commit, потрібно встановити значення для commit.template:

$ git config --global commit.template ~/.gitmessage.txt
$ git commit

Після цього, під час створення коміту, ваш редактор буде відкривати щось на зразок наступного в якості заповнювача для повідомлення коміту:

Subject line (try to keep under 60 characters)

Multi-line description of commit,
feel free to be detailed.

[Ticket: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   lib/test.rb
#
~
~
".git/COMMIT_EDITMSG" 14L, 297C

Якщо ваша команда має певні вимоги до повідомлення коміту, то встановлення шаблону для цих вимог у системі та налаштування Git, щоб він використовував його за замовчуванням, збільшить шанси регулярного дотримання цих вимог.

core.pager

Це налаштування визначає, який прогортач сторінок використовується, коли Git прогортає виведення, таке як log і diff. Ви можете встановити його в значення more чи ваш улюблений прогортач сторінок (за замовчуванням — це less), чи вимкнути його, задавши як значення порожній рядок:

$ git config --global core.pager ''

Якщо ви виконаєте це, Git буде відображати увесь результат всіх команд, незалежно від його довжини.

user.signingkey

Якщо ви створюєте підписані анотовані теґи (як це обговорювалось у Підписання праці), то встановлення вашого GPG ключа підпису в конфігураційних налаштуваннях зробить це простішим. Вкажіть ID вашого ключа наступним чином:

$ git config --global user.signingkey <gpg-key-id>

Тепер ви можете підписувати теґи без необхідності кожного разу вказувати ваш ключ у команді git tag:

$ git tag -s <tag-name>

core.excludesfile

Ви можете задати шаблони у файлі .gitignore вашого проекту для того, щоб Git не бачив їх як невідслідковувані та не намагався індексувати при виконанні команди git add на них, як це обговорювалось у Ігнорування файлів.

Але іноді виникає потреба ігнорувати певні файли у всіх сховищах, з якими ви працюєте. Якщо ваш комп’ютер працює на macOS, ви, напевно, знайомі з файлами .DS_Store. Якщо ж ви надаєте перевагу редактору Emacs, то знаєте про файли, що їхні назви закінчуються на ~ чи .swp.

Ця опція дозволяє написати щось на зразок глобального файлу .gitignore. Якщо ви створите файл ~/.gitignore_global з наступним вмістом:

*~
.*.swp
.DS_Store

…та виконаєте команду git config --global core.excludesfile ~/.gitignore_global, то Git більше ніколи не буде турбувати вас щодо цих файлів.

help.autocorrect

Якщо ви помиляєтесь при наборі команди, то виводиться щось подібне до цього:

$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.

Did you mean this?
    checkout

Git послужливо намагається зрозуміти, що ви мали на увазі, але відмовляється виконувати це. Якщо встановити значення help.autocorrect рівним 1, то Git буде все ж таки виконувати цю команду:

$ git chekcout master
WARNING: You called a Git command named 'chekcout', which does not exist.
Continuing under the assumption that you meant 'checkout'
in 0.1 seconds automatically...

Зверніть увагу на це дивне “0.1 seconds”. Насправді значення опції help.autocorrect є цілим числом, що представляє десяті секудни. Тому, якщо встановити його рівним 50, то Git дасть вам 5 секунд, щоб змінити свою думку перед виконанням відкоректованої команди.

Кольори у Git

Git повністю підтримує кольорове виведення у терміналі, що робить візуальний розбір результатів виконання команд значно швидшим та легшим. Чимало опцій можуть допомогти налаштувати кольори відповідно до ваших вподобань.

color.ui

Git автоматично розфарбовує більшу частину свого виведення, але є головний вимикач, якщо вам не подобається така поведінка. Щоб вимкнути кольорове виведення Git у терміналі, зробіть наступне:

$ git config --global color.ui false

Типовим налаштуванням є auto, що розфарбовує виведення, коли воно йде прямо у термінал, але уникає керування кольором, коли виведення переадресовується у канал чи файл.

Ви також можете встановити його у значення always для ігнорування різниці між терміналами та каналами. Вам рідко хотітиметься цього; у більшості сценаріїв, якщо вам потрібне кольорове кодування у переадресованому виведенні, можна передати параметр --color в команду Git, щоб змусити його використовувати кольорове кодування. Типове значення майже завжди є тим, чого ви бажаєте.

color.*

Якщо ви хочете вказати більш конкретно, яку команду розфарбовувати і як — Git постачає налаштування кольору для конкретних команд-дієслів. Кожна з них може бути задана в true, false або always:

color.branch
color.diff
color.interactive
color.status

На додаток, кожне з цих підналаштувань можна використовувати для встановлення конкретного кольору для частини виводу, якщо ви бажаєте змінити кожен колір. Наприклад, щоб встановити метадані у вашому виводі різниці в синій текст, чорне тло та грубий шрифт, ви можете виконати

$ git config --global color.diff.meta "blue black bold"

Ви можете встановити колір у будь-яке з наступних значень: normal, black, red, green, yellow, blue, magenta, cyan, чи white. Якщо вам потрібні такі атрибути як bold з попереднього прикладу, то можете вибирати з bold, dim, ul (підкреслено), blink та reverse (переставити тло та текст).

Зовнішні інструменти зливання (merge) та різниці (diff)

Хоча Git має вбудовану імплементацію отримання різниці, яку ми використовували в цій книзі, ви можете натомість налаштувати зовнішній інструмент. Ви також можете налаштувати графічний інструмент для розв’язання конфліктів зливання замість того, щоб розв’язувати їх вручну. Ми продемонструємо налаштування Perforce Visual Merge Tool (P4Merge) для відображення різниці та розв’язання конфліктів, адже це гарна графічна програма та вона безкоштовна.

Якщо ви бажаєте спробувати її, P4Merge працює на всіх розповсюджених платформах, отже ви маєте бути в змозі це зробити. Ми використовуватимемо в прикладах шляхи, які працюють на системах Mac та Linux; для Windows, вам доведеться замінити /usr/local/bin на шлях до програми у вашому середовищі.

Спочатку, завантажте P4Merge з Perforce. Далі, ви налаштуєте зовнішні скрипти обгортки для виконання своїх команд. Ми використовуватимемо шлях Mac для програми; на інших системах, він буде там, де встановлено файл p4merge. Налаштуйте обгортку для зливання під назвою extMerge, яка викликає програму з усіма опціями:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*

Обгортка diff перевіряє, чи дійсно отримано сім параметрів, та передає два з них до вашого скрипта зливання. Типово, Git передає наступні аргументи до програми diff:

path old-file old-hex old-mode new-file new-hex new-mode

Оскільки вам потрібні лише old-file та new-file, ви використовуєте обгортку, щоб передати лише потрібні.

$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"

Вам також потрібно переконатися, що ці програми виконанні:

$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff

Тепер ви можете налаштувати свій конфігураційний файл, щоб використовувалися ваші власні інструменти відображення різниці та розв’язання конфліктів. Для цього потрібні декілька налаштувань: merge.tool, щоб сказати Git яку стратегію використовувати, mergetool.<інструмент>.cmd, щоб задати, як виконувати команду, mergetool.<інструмент>.trustExitCode, щоб сказати Git, чи означає код виходу програми успішність розв’язання чи ні, а також diff.external, щоб сказати Git, яку команду треба виконувати для відображення різниці. Отже, ви можете або виконати наступні чотири команди config

$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
  'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.extMerge.trustExitCode false
$ git config --global diff.external extDiff

або відредагувати файл ~/.gitconfig, щоб додати ці рядки:

[merge]
  tool = extMerge
[mergetool "extMerge"]
  cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
  trustExitCode = false
[diff]
  external = extDiff

Після того як це зроблено, якщо ви виконаєте команду diff, на кшталт такої:

$ git diff 32d1776b1^ 32d1776b1

Замість отримання різниці в командному рядку, Git запустить P4Merge, який виглядає приблизно так:

P4Merge.
Figure 142. P4Merge.

Якщо ви спробуєте злити дві гілки та отримаєте конфлікти злиття, то можете виконати команду git mergetool; вона запускає P4Merge, щоб дозволити вам розв’язати конфлікти цим графічним інструментом.

У такому налаштуванні обгорток зручно те, що ви легко можете змінити інструменти diff та merge. Наприклад, щоб змінити свої extDiff та extMerge так, щоб вони натомість викликали KDiff3, усе, що вам треба зробити — змінити файл extMerge:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*

Тепер, Git використовуватиме інструмент KDiff3 для відображення різниць та розв’язання конфліктів зливання.

Git одразу має налаштування для використання великої кількості інших інструментів розв’язання конфліктів без необхідності налаштування команд. Щоб побачити список підтримуваних інструментів, спробуйте:

$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
        emerge
        gvimdiff
        gvimdiff2
        opendiff
        p4merge
        vimdiff
        vimdiff2

The following tools are valid, but not currently available:
        araxis
        bc3
        codecompare
        deltawalker
        diffmerge
        diffuse
        ecmerge
        kdiff3
        meld
        tkdiff
        tortoisemerge
        xxdiff

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.

Якщо ви не зацікавлені у використанні KDiff3 для різниць, а надаєте йому перевагу лише для розв’язання конфліктів, та команда kdiff3 є у вашому path, то можете виконати

$ git config --global merge.tool kdiff3

Якщо ви виконаєте це замість налаштування файлів extMerge та extDiff, то Git буде використовувати KDiff3 для розв’язання конфліктів, а для відображення різниць звичайний інструмент Git.

Форматування та пробільні символи.

Проблеми з форматуванням та пробільними символами є одними з найбільш дратуючих та невловимих, та багато розробників стикаються з ними під час співпраці, особливо міжплатформевої. Латки чи інша співпраця дуже легко можуть запровадити непомітні зміни пробільних символів, адже редактори тихо впроваджують їх, та якщо файли колись бували на системі Windows, усі символи кінця рядка можуть бути змінені. Git має декілька опцій, щоб зарадити з цим.

core.autocrlf

Якщо ви програмуєте під Windows та працюєте з людьми, які цього не роблять (чи навпаки), то колись ви, імовірно, отримаєте проблеми з кінцями рядків. Таке трапляється через те, що Windows використовує і символ повернення каретки, і символи зміни рядка для нових рядків у файлах, в той час як системи Mac та Linux використовують лише символ нового рядка. Це непомітно, проте неймовірно навісний факт для міжплатформової праці; багато редакторів Windows тихо замінюють існуючі кінці рядків LF на CRLF, або додають обидва символи, коли користувач натискає клавішу ентер.

Git може впоратись з цим: автоматично конвертувати кінці рядків CRLF до LF, коли ви додаєте файл до індексу, та навпаки, коли ви отримуєте код до файлової системи. Ви можете увімкнути цей функціонал за допомогою налаштування core.autocrlf. Якщо ви працюєте на машині Windows, то встановлення цього в true конвертує LF до CRLF під час отримання коду:

$ git config --global core.autocrlf true

Якщо ви на системі Linux чи Mac, які використовують кінці рядків LF, то ви не бажаєте, щоб Git автоматично конвертував їх під час отримання файлів; втім, якщо файл з CRLF випадково впроваджено, то ви можете бажати, щоб Git це виправив. Ви можете сказати Git перетворювати CRLF на LF під час створення коміту, проте не навпаки, якщо встановете core.autocrlf у значення input:

$ git config --global core.autocrlf input

Таке схема має залишити вам символи CRLF після отримань на Windows, та символ LF на системах Mac та Linux у сховищі.

Якщо ви програміст Windows та розробляєте проект лише для Windows, то можете вимкнути цю функціональність, тобто записувати повернення каретки до сховища, якщо встановите це конфігураційне значення у false:

$ git config --global core.autocrlf false

core.whitespace

Git одразу налаштовано визначати та виправляти деякі проблеми з пробільними символами. Він може шукати шість головних проблем з пробільними символами — три типово ввімкнуті та можуть бути вимкнені, а інші три типово вимкнені, проте можуть бути активовані.

Типово ввімкнені: blank-at-eol, яка шукає пробіли наприкінці рядка; blank-at-eof, яка помічає порожні рядки наприкінці файлу; та space-before-tab, яка шукає пробіли перед табами на початку рядка.

Три типово вимкнені, які можна увімкнути: indent-with-non-tab, яка шукає рядки, які починаються з пробілів замість табів (та контролюється опцією tabwidth); tab-in-indent, яка слідкує за табами у відступах; та cr-at-eol, яка каже Git, що переведення каретки наприкінці рядків це нормально.

Ви можете сказати Git, які з них ви бажаєте ввімкнути, якщо встановите налаштування core.whitespace у значення, які ви бажаєте щоб працювали чи ні, розділені комами. Ви можете вимкнути опцію, додавши - перед її назвою, або залишити типове значення, просто не зазначивши в рядку налаштувань.. Наприклад, якщо ви бажаєте встановити все, крім space-before-tab, то можете зробити таке (trailing-space — це скорочення для двох опцій: blank-at-eol та blank-at-eof):

$ git config --global core.whitespace \
    trailing-space,-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol

Або ви можете вказати лише частину, що відрізняється від типових значень:

$ git config --global core.whitespace \
    -space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol

Git знаходитиме ці проблеми, коли ви виконуєте команду git diff та намагатиметься розфарбувати їх, щоб ви могли виправити їх перед збереженням коміту. Він також використовує ці значення, щоб допомогти застосовувати латки командою git apply. Коли ви застосовуєте латки, ви можете попросити Git попереджати вас, якщо вони містять зазначені проблеми пробільних символів:

$ git apply --whitespace=warn <patch>

Або ви можете зробити так, щоб Git намагався автоматично виправити ці проблеми перед застосуванням латки:

$ git apply --whitespace=fix <patch>

Ці опції також стосуються команди git rebase. Якщо ви зберегли в коміті помилки пробільних символів, проте ще не надіслали зміни, то можете виконати git rebase --whitespace=fix, щоб Git автоматично виправив ці проблеми під час переписування латок.

Конфігурація сервера

Геть не так багато конфігураційних опцій існує для серверної частини Git, проте є декілька цікавих, які ви можете запам’ятати.

receive.fsckObjects

Git має можливість переконатися, що кожен отриманий під час push об’єкт досі збігається зі SHA-1 сумою та вказує на чинні об’єкти. Втім, він типово цього не робить; ця операція забирає багато часу, та може уповільнити операцію, особливо з великими сховищами чи надсиланнями. Якщо ви бажаєте, щоб Git перевіряв цілісність об’єктів під час кожного надсилання, ви можете змусити його це робити, якщо встановите налаштування receive.fsckObjects у true.

$ git config --system receive.fsckObjects true

Тепер, Git перевірятиме цілісність вашого сховища перед прийняттям кожного надсилання, щоб переконатись, що пошкодженні (чи шкідливі) клієнти не впроваджують зіпсованих даних.

receive.denyNonFastForwards

Якщо ви перебазовуєте коміти, які вже надсилали та потім знову намагаєтесь надіслати, чи іншим чином намагаєтесь надіслати коміт до віддаленої гілки, яка не містить коміту, на який зараз вказує гілка, то вам відмовлять. Це зазвичай гарна політика; проте у випадку перебазування, ви можете вирішити, що знаєте, що робите, та примусити оновлення віддаленої гілки за допомогою опції -f команди push.

Щоб сказати Git відмовляти примусовим надсиланням, встановіть receive.denyNonFastForwards:

$ git config --system receive.denyNonFastForwards true

Ви також можете досягти цього за допомогою серверного гаку на отримання, що ми розглянемо трохи пізніше. Цей підхід дозволяє вам робити складніші речі, наприклад відмовляти не перемотуванням для деяких користувачів.

receive.denyDeletes

Один з манівців до політики denyNonFastForwards для користувачів — вилучити гілку, а потім надіслати зміни до нового посилання. Щоб уникнути цього, встановіть receive.denyDeletes у true:

$ git config --system receive.denyDeletes true

Це відмовляє будь-яким вилученням гілок чи теґів — жоден користувач не зможе цього робити. Щоб вилучити віддалену гілку, вам доведеться вилучати файли посилань з сервера вручну. Існують цікавіши методи робити це для окремих користувачів на базі ACL, про що ви дізнаєтесь в Приклад політики користування виконуваної Git-ом.