-
1. Начало
- 1.1 За Version Control системите
- 1.2 Кратка история на Git
- 1.3 Какво е Git
- 1.4 Конзолата на Git
- 1.5 Инсталиране на Git
- 1.6 Първоначална настройка на Git
- 1.7 Помощна информация в Git
- 1.8 Обобщение
-
2. Основи на Git
-
3. Клонове в Git
-
4. GitHub
-
5. Git инструменти
- 5.1 Избор на къмити
- 5.2 Интерактивно индексиране
- 5.3 Stashing и Cleaning
- 5.4 Подписване на вашата работа
- 5.5 Търсене
- 5.6 Манипулация на историята
- 5.7 Мистерията на командата Reset
- 5.8 Сливане за напреднали
- 5.9 Rerere
- 5.10 Дебъгване с Git
- 5.11 Подмодули
- 5.12 Пакети в Git (Bundling)
- 5.13 Заместване
- 5.14 Credential Storage система
- 5.15 Обобщение
-
6. Настройване на Git
- 6.1 Git конфигурации
- 6.2 Git атрибути
- 6.3 Git Hooks
- 6.4 Примерна Git-Enforced политика
- 6.5 Обобщение
-
7. Git и други системи
- 7.1 Git като клиент
- 7.2 Миграция към Git
- 7.3 Обобщение
-
8. Git на ниско ниво
- 8.1 Plumbing и Porcelain команди
- 8.2 Git обекти
- 8.3 Git референции
- 8.4 Packfiles
- 8.5 Refspec спецификации
- 8.6 Транспортни протоколи
- 8.7 Поддръжка и възстановяване на данни
- 8.8 Environment променливи
- 8.9 Обобщение
-
9. Приложение A: Git в други среди
-
10. Приложение B: Вграждане на Git в приложения
- 10.1 Git от команден ред
- 10.2 Libgit2
- 10.3 JGit
- 10.4 go-git
- 10.5 Dulwich
-
A1. Приложение C: Git команди
- A1.1 Настройки и конфигурация
- A1.2 Издърпване и създаване на проекти
- A1.3 Snapshotting
- A1.4 Клонове и сливане
- A1.5 Споделяне и обновяване на проекти
- A1.6 Инспекция и сравнение
- A1.7 Дебъгване
- A1.8 Patching
- A1.9 Email команди
- A1.10 Външни системи
- A1.11 Административни команди
- A1.12 Plumbing команди
6.1 Настройване на Git - Git конфигурации
Досега прегледахме основите на работата с Git, представихме и множество инструменти, помагащи ни да работим по-лесно и ефективно. В тази глава ще видим как да накараме Git да работи в по-специфични режими посредством няколко важни конфигурационни настройки и hooks системата. С тези инструменти е лесно да накарате Git да работи точно както желаете вие, вашия екип или компанията ви.
Git конфигурации
Както погледнахме накратко в Начало, можете да използвате командата git config
за манипулация на конфигурационни настройки.
Едно от първите неща, които направихме беше да зададем име и имейл адрес:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
Сега ще разгледаме повече интересни опции, които можем да променяме по този начин, така че да настроим по-фино поведението на Git системата.
Първо, кратък преглед: Git използва серия от конфигурационни файлове, за да определи нестандартното поведение, което бихте могли да искате.
Първото място, което Git проверява, е system-wide файла [path]/etc/gitconfig
, който съдържа множество настройки валидни за всички потребители и всички хранилища в машината.
Ако подадете опцията --system
на git config
, командата чете и пише точно в този файл.
След това Git търси файла ~/.gitconfig
(или ~/.config/git/config
) в потребителските директории, в който се съхраняват настройки специално за конкретния потребител на операционната система.
Този е засегнатия файл, когато подавате на командата аргумента --global
.
Най-накрая Git проверява за конфигурационни настройки във файл в конкретното текущо хранилище (.git/config
).
Тези стойности са специфични само за конкретното хранилище и се подават с аргумента --local
към git config
.
Ако не укажете аргумент за обхват на командата, именно това локално ниво се използва по подразбиране.
Всяко от тези “нива” (system, global, local) презаписва стойностите от предишното, така че стойностите в .git/config
са с приоритет пред тези в [path]/etc/gitconfig
например.
Забележка
|
Конфигурационните файлове на Git са чист текст и можете да редактирате файловете директно, спазвайки съответния синтаксис.
Все пак, вероятно е по-лесно да използвате |
Основни конфигурации на клиента
Конфигурационните опции, които Git използва попадат в две главни категории: клиентска и сървърна. Болшинството от опции са клиентски — настройват персоналните ви предпочитания за работа. Поддържат се огромен брой опции, но голяма част от тях се използват само в специфични случаи, ето защо ще разгледаме най-популярните и полезни. Ако искате списък на всички, можете да изпълните:
$ man git-config
Тази команда изброява и обяснява всички налични опции в подробности. Алтернативно място да получите тази информация е https://git-scm.com/docs/git-config.
core.editor
По подразбиране, Git използва настро̀ения за вашия персонален акаунт текстов редактор през environment променливите 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]
Забелязваме как този шаблон припомня на разработчика да поддържа subject реда кратък (за по-красив git log --oneline
изход), да добавя подробности под него и да упоменава issue или номер на тикет в bug tracker система, ако има такава.
Задаването на шаблона се прави с командата:
$ git config --global commit.template ~/.gitmessage.txt
$ git commit
След което, текстовият редактор ще изглежда така, когато бъде стартиран:
Subject line (try to keep under 50 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
Ако екипът ви спазва commit-message политика, тогава използването на един такъв шаблон би било много полезно и увеличава шансовете за стриктно спазване на политиката.
core.pager
Тази настройка определя кой пейджър да се използва, когато Git странира изхода от команди като log
и diff
.
Можете да я настроите на more
или на нещо друго (по подразбиране е less
), а също и можете да изключите странирането задавайки ѝ празен стринг:
$ git config --global core.pager ''
Така Git ще показва наведнъж целия изход от всички команди без значение от дължината му.
user.signingkey
Ако правите signed annotated тагове (както видяхме в Подписване на вашата работа), задаването на вашия GPG подписващ ключ като конфигурационна настройка, ще ви спести писане. Задава се така:
$ git config --global user.signingkey <gpg-key-id>
Сега можете да подписвате тагове без да трябва да указвате ключа си всеки път, когато пуснете git tag
:
$ git tag -s <tag-name>
core.excludesfile
В Игнориране на файлове видяхме как да създаваме маски в .gitignore
файл, така че Git да не вижда и да не се опитва да индексира определени файлове в проекта.
Понякога обаче е по-удобно да игнорирате дадени файлове във всички хранилища, с които работите.
Ако използвате macOS, вероятно сте запознати с .DS_Store
файловете.
Ако предпочитаният ви редактор е Emacs или Vim, знаете за файловите имена, които завършват на ~
или .swp
.
Тази настройка дава възможност за нещо като глобален .gitignore
файл.
Ако създадете файл ~/.gitignore_global
с това съдържание:
*~
.*.swp
.DS_Store
…и изпълните git config --global core.excludesfile ~/.gitignore_global
, Git въобще няма да обръща внимание на подобни файлове във всички хранилища.
help.autocorrect
Ако сбъркате команда, Git показва нещо от рода:
$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.
The most similar command is
checkout
Услужливо ви предлага да отгатне какво имате предвид, но все пак не изпълнява предполагаемата команда.
Ако обаче зададете 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 config --global color.ui false
Стойността по подразбиране е auto
, което оцветява изхода в терминала, но пропуска color-control кодовете, ако изходът е пренасочен към pipe или към файл.
Ако искате оцветяване навсякъде, настройката също приема и стойността always
.
Вероятно малко хора ще искат да правят това, в повечето случаи ако искате цветове в пренасочения изход, можете да подадете флага --color
към конкретната единична команда.
В почти всички случаи настройките по подразбиране ще са това, което очаквате.
color.*
Можете да бъдете и още по-прецизни в избора на това изходът от кои команди да се оцветява и как точно.
Всяка от тези опции може да е true
, false
, или always
:
color.branch color.diff color.interactive color.status
В допълнение, всяка от тях има и поднастройки, които можете да използвате за да задавате специфични цветове на част от изхода им и да коригирате всеки един от зададените цветове. Например, ако искате метаданните във вашия diff изход да са със сини символи на черен фон и удебелен шрифт, може да направите така:
$ git config --global color.diff.meta "blue black bold"
Цветовете приемат стойности: normal
, black
, red
, green
, yellow
, blue
, magenta
, cyan
, или white
.
Ако искате специфичен атрибут за шрифта както беше bold преди малко, налични са вариантите bold
, dim
, ul
(underline), blink
, и reverse
(размяна на цветовете на символите и фона).
Външни Merge и Diff инструменти
Въпреки, че Git има собствена вътрешна diff имплементация (която виждаме в действие в настоящата книга), можете да използвате и външен diff инструмент. Можете да си настроите графичен merge-conflict-resolution инструмент, вместо да трябва да коригирате конфликтите ръчно. Ще покажем как се настройва безплатния и удобен инструмент Perforce Visual Merge Tool (P4Merge) за да правите вашите diffs и merge resolutions.
Ако искате да го пробвате, P4Merge работи на всички основни платформи.
В примерите ще използваме пътища, които се ползват в macOS и Linux, за Windows ще трябва да смените /usr/local/bin
към съответния път в конкретната инсталация.
За начало, изтеглете P4Merge от Perforce.
След това, ще създадем външни wrapper скриптове за изпълнение на командите ви.
Ще използваме macOS пътя за изпълнимия файл, в други системи той ще е мястото, където се намира p4merge
програмата.
Създаваме merge wrapper скрипт наречен extMerge
, който извиква програмата с всички необходими аргументи:
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*
Скриптът за diff от своя страна проверява за подадени седем аргумента и изпраща два от тях към merge скрипта. По подразбиране, Git изпраща следните аргументи към diff програмата:
path old-file old-hex old-mode new-file new-hex new-mode
Понеже искаме само old-file
и new-file
аргументите, използваме wrapper скрипта, за да подаваме само тях.
$ 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.<tool>.cmd
за начина на стартиране на командата, mergetool.<tool>.trustExitCode
за да укажем на Git, че кода на изход на програмата индикира успешно/неуспешно сливане, и diff.external
за командата използвана за diff.
Така може да изпълните следните 4 конфигурационни команди:
$ 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, който би изглеждал подобно:
Ако опитате да слеете два клона и получите конфликти, може да изпълните git mergetool
и тя от своя страна ще стартира P4Merge за да ви позволи да ги разрешите в графичен стил.
Удобното нещо на тези wrapper настройки е, че лесно можете да променяте diff и merge инструментите си.
Например, ако желаете extDiff
и extMerge
скриптовете да пускат KDiff3 програмата, просто трябва да редактирате файла extMerge
:
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
Сега вече Git ще използва KDiff3 за показване на diff информация и разрешаване на конфликти.
Git също така идва с известен брой предварително зададени външни merge-resolution инструменти за да не се налага да правите командната конфигурация. За да видите списък с тях, пробвайте това:
$ 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 за diff, но искате да го използвате за корекция на конфликти и kdiff3 командата е в пътя ви, можете да изпълните:
$ git config --global merge.tool kdiff3
Ако направите това вместо да създавате extMerge
и extDiff
скриптовете, Git ще ползва KDiff3 за конфликти и вътрешния Git diff инструмент за diff визуализация.
Форматиране и празни символи
Проблемите с форматирането и празните символи са сред най-досадните неща, с които разработчиците се сблъскват по време на съвместна работа и особено ако работят на различни платформи. Много е лесно пачове или друга съвместна работа да внесат незабележими whitespace промени, защото редакторите ги вкарват задкулисно и ако файловете ви се озоват на Windows система, знаците им за край на ред може да се променят без предупреждение. Git разполага с няколко конфигурационни опции за да ви помогне в такива случаи.
core.autocrlf
Ако програмирате под Windows, а колегите ви не (или обратното), твърде вероятно е да възникнат проблемни ситуации в даден етап. Това е защото Windows използва за край на ред във файловете и двата символа (carriage-return и linefeed), докато под macOS/Linux се използва само linefeed. Това е незабележима за окото разлика, но постоянно предизвиква проблеми при многоплатформена работа, много редактори под Windows без да питат конвертират наличните LF знаци за край на ред в CRLF.
Git може да се справи с това конвертирайки CRLF символите в LF, когато добавяте файл в индекса и обратното, когато извличате файл в работната директория.
Може да контролирате това поведение през настройката core.autocrlf
.
Ако сте на Windows машина, задайте true
— това ще конвертира LF символите в CRLF, когато извличате файловете:
$ git config --global core.autocrlf true
Ако сте на Linux или macOS, няма да искате автоматично конвертиране, обаче ако някой файл с CRLF внезапно се появи, бихте желали Git да го коригира.
Можете да зададете CRLF към LF конвертирането да се прави при къмит задавайки стойността input
за core.autocrlf
:
$ git config --global core.autocrlf input
Това положение би трябвало да остави CRLF символите, когато извличате под Windows и LF символите под macOS и Linux, както и в хранилището.
Ако сте Windows програмист и работите по Windows проект, тогава може да изключите тази функционалност и да записвате CR символите в хранилището задавайки false
за опцията:
$ git config --global core.autocrlf false
core.whitespace
Git също така разполага с възможност да разпознава и коригира някои проблеми с празните символи. Налични са инструменти за 6 главни ситуации — три са разрешени по подразбиране и могат да се изключат и три други по подразбиране са изключени, но могат да се активират.
Трите включени опции са blank-at-eol
, която търси за интервали в края на ред; blank-at-eof
, която усеща празни редове в края на файла, и space-before-tab
търсеща за интервали преди табулации в началото на редовете.
Изключените фабрично опции са indent-with-non-tab
, която търси редове започващи с интервали вместо с табулации (и се контролира с tabwidth
опцията); tab-in-indent
, която следи за наличието на табулации в indentation частта на редовете; и cr-at-eol
, която казва на Git, че carriage return символите в края на редовете са OK.
Можете да кажете на 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 да ви предупреждава, ако те съдържат whitespace проблеми:
$ git apply --whitespace=warn <patch>
Или може да кажете на Git да се опита автоматично да ги реши преди да приложи пача:
$ git apply --whitespace=fix <patch>
Тези опции важат и за командата git rebase
.
Ако сте къмитнали whitespace нередности, но все още не сте публикували в upstream хранилището, можете да изпълните git rebase --whitespace=fix
и така Git ще се опита да коригира нещата по същия начин, по който пренаписва пачовете.
Сървърни конфигурации
Конфигурационните опции за сървърната роля на Git не са толкова много на брой, но някои от тях заслужават да бъдат посочени.
receive.fsckObjects
Git може да проверява дали всеки обект получен по време на публикуване все още съответства на очакваната си SHA-1 стойност и дали сочи към валидни обекти.
Но това по подразбиране не се прави, защото е ресурсоемка операция и може да причини забавяне при големи хранилища.
Може да включите проверката задавайки true за receive.fsckObjects
:
$ git config --system receive.fsckObjects true
Сега Git при всеки push ще проверява интегритета на хранилището преди да го приеме, така че некоректните (или умишлено злонамерени) клиенти да не могат да внесат повредени данни.
receive.denyNonFastForwards
Ако пребазирате къмити, които вече сте публикували и се опитате да ги публикувате пак, или пък се опитате да публикувате къмит към отдалечен клон и този къмит не съдържа къмита, към който този клон текущо сочи, ще ви бъде отказано.
Това по принцип е добра политика, но в случая на rebase може да установите, че знаете какво точно правите и може да форсирате обновяването на отдалечения клон с -f
флага на push командата.
Може да забраните форсираните публикувания задавайки receive.denyNonFastForwards
:
$ git config --system receive.denyNonFastForwards true
Друг начин да направите това е чрез сървърни receive hooks, които ще разгледаме накратко. Този подход позволява да правим много по-сложни неща като например отказ за non-fast-forwards само за определени потребители.
receive.denyDeletes
По-напредналите потребители могат да заобиколят denyNonFastForwards
политиките изтривайки клона и след това публикувайки го отново с новата референция.
За да избегнете това, задайте receive.denyDeletes
със стойност true:
$ git config --system receive.denyDeletes true
Това забранява изтриването на клонове и тагове — никой потребител няма да може да го прави. За да изтриете отдалечени клонове ще трябва да изтриете ref файловете от сървъра ръчно. Съществуват и по-интересни начини да правите това на per-user принцип през ACL, както ще видим в Примерна Git-Enforced политика.