Псевдонимы и кастомизация .gitconfig

Рейтинг: 71.7% · 16 голосов
Самый подробный курс по Git - от первого коммита до объектной базы и packfiles. Терминал и первый репозиторий, ветки и слияние, конфликты, удалённая работа и форджи (GitHub, GitLab), rebase и переписывание истории, спасение кода через reflog и fsck, stash и worktree, bisect и blame, подмодули и монорепо, хуки и подпись коммитов, внутреннее устройство и масштаб. Для новичков и профи. Актуально на 2026 (Git 2.54, дорожная карта 3.0).
Ответить
Аватара пользователя
Pavel_Git
Сообщения: 52
Зарегистрирован: 11 май 2026, 05:31

Псевдонимы и кастомизация .gitconfig

Сообщение Pavel_Git »

Оглавление курса (52)
  1. Что такое контроль версий и почему победил Git
  2. Установка Git на Windows, macOS и Linux и первая настройка
  3. Терминал и как спрашивать у Git: выживание в командной строке
  4. Ментальная модель Git: три состояния, коммит-снимок и граф
  5. Первый репозиторий: init, add, commit, status
  6. Просмотр изменений: status, diff и индексация по частям
  7. История проекта: git log, диапазоны и поиск
  8. .gitignore: что не должно попасть в репозиторий
  9. .gitattributes: окончания строк, бинарники и атрибуты
  10. Ветки как указатели: branch, switch и detached HEAD
  11. Слияние веток: fast-forward против трёхстороннего merge
  12. Конфликты слияния: анатомия и уверенное разрешение
  13. Практикум: твой первый день с Git от нуля до push
  14. Удалённые репозитории: remote, fetch, базовый pull и refspec
  15. git push: безопасная отправка и защита от перезаписи
  16. Клонирование: shallow, partial clone, bundle и backfill
  17. GitHub, GitLab и форки: pull request, rulesets и защита веток
  18. Рабочие процессы команды: GitFlow, GitHub Flow, trunk-based
  19. Merge queue и merge trains: безопасное вливание в trunk
  20. Культура code review и Conventional Commits
  21. git reset: три дерева и отмена индексации и коммитов
  22. git revert: безопасная отмена в общей истории
  23. Правка последнего коммита: git commit --amend
  24. git rebase: пересадка истории и золотое правило
  25. Интерактивный rebase: переписать серию коммитов
  26. git cherry-pick: перенос отдельных коммитов
  27. Stacked diffs: цепочка зависимых PR
  28. Массовое переписывание истории: git filter-repo и git replace
  29. git reflog: журнал, который помнит всё
  30. Восстановление утерянных коммитов, веток и файлов
  31. Откат опасных операций: reset --hard, сломанный rebase, плохой merge
  32. git stash: тайник для незавершённой работы
  33. git worktree: несколько рабочих деревьев одного репозитория
  34. git bisect: бинарный поиск регрессии
  35. git blame, mailmap и археология кода
  36. Теги, релизы, archive и bundle
  37. Подмодули: внешние репозитории внутри проекта
  38. Subtree, монорепозитории и sparse-checkout
  39. Git LFS и большие файлы
  40. Вспомогательные команды: clean, mv, rm, restore
  41. Псевдонимы и кастомизация .gitconfig (вы здесь)
  42. Хуки Git: автоматизация на клиенте и сервере
  43. Подпись коммитов и тегов: SSH, GPG и Sigstore
  44. Внутреннее устройство I: объектная база Git
  45. Внутреннее устройство II: ссылки, HEAD, notes и reftable
  46. Внутреннее устройство III: индекс, packfiles, gc и обслуживание
  47. От SHA-1 к SHA-256: переход на новый хеш
  48. Огромные репозитории: partial clone, FSMonitor, Scalar
  49. Git в CI/CD: shallow, кеш, merge_group и безопасность
  50. Куда движется Git: дорожная карта 3.0 и экосистема
  51. Профессиональный setup: собираем рабочее окружение Git
  52. 30+ типичных ошибок Git и как из них выбираться
Ты набираешь git status и git checkout по сто раз в день. Двести нажатий клавиш на ровном месте. А ещё периодически коммитишь в рабочий репозиторий с личной почты, потому что забыл переключить user.email, и теперь в истории компании висит твой gmail. И каждый раз, когда два аккаунта на GitHub дерутся за один SSH-ключ, ты гуглишь одно и то же. Всё это лечится один раз - грамотным .gitconfig. В этом уроке разберём настройку gitconfig до винтика: git псевдонимы (alias), составные shell-алиасы, условные includeIf для разных личностей, multi-SSH через ~/.ssh/config и настройки качества жизни, которые экономят часы. В конце - готовый профессиональный конфиг, который можно забрать целиком.

Где живёт конфиг и как он читается

Git не хранит настройки в одном месте. Он склеивает их из нескольких файлов, и порядок чтения важен - что прочитано позже, то и перекрывает прежнее. Уровней четыре, от самого общего к самому частному:
  • system - /etc/gitconfig, для всех пользователей машины. Трогаешь редко.
  • global - ~/.gitconfig (или ~/.config/git/config), твой личный, на все репозитории. Тут живёт 90% настроек.
  • local - .git/config внутри конкретного репозитория. Перекрывает global для этого проекта.
  • worktree - .git/config.worktree, отдельный конфиг на ворктри, если включён extensions.worktreeConfig.
Главное правило: более частный уровень побеждает. Поставил user.email глобально, но в .git/config рабочего проекта он другой - в этом проекте применится локальный. Проверить, кто и откуда выиграл, помогает один незаменимый флаг - origin показывает источник каждого значения:

Код: Выделить всё

$ git config --list --show-origin --show-scope
global  file:/home/dev/.gitconfig       user.name=Anton K
global  file:/home/dev/.gitconfig       core.pager=delta
local   file:.git/config                user.email=anton@bigcorp.io
local   file:.git/config                remote.origin.url=git@github.com:bigcorp/api.git
Видишь, откуда пришёл каждый ключ. Когда поведение Git необъяснимо - первым делом сюда. А узнать конкретное эффективное значение и его источник можно точечно:

Код: Выделить всё

$ git config --show-origin user.email
file:.git/config        anton@bigcorp.io
Формат файла - это INI: секции в квадратных скобках, ключи внутри. Сам файл - обычный текст, его можно править руками, а можно командой git config user.name "Anton K". Руками часто удобнее, особенно для алиасов.

Изображение

git alias: сокращения, которые экономят часы

Псевдоним (alias) - это просто новое имя для команды. Настройка простых алиасов через git config alias делается так:

Код: Выделить всё

$ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
После этого git st работает как git status. В файле это превращается в секцию:

Код: Выделить всё

[alias]
    st = status
    co = checkout
    br = branch
    ci = commit
Важная механика: правую часть Git дописывает к git и любые твои аргументы добавляет в конец. То есть git co -b feature разворачивается в git checkout -b feature. Можно зашивать флаги прямо в алиас - git псевдонимы это не только переименование, но и заготовленные команды:

Код: Выделить всё

[alias]
    last = log -1 HEAD --stat
    unstage = reset HEAD --
    amend = commit --amend --no-edit
    aliases = config --get-regexp ^alias\\.
git unstage file.txt снимет файл со стейджа - читается куда понятнее, чем reset. git amend подхватит изменения в последний коммит, не трогая сообщение. А git aliases напечатает все твои алиасы - удобно, когда забыл, что насочинял.

Самый ценный из полезных алиасов git - красивый граф истории. Классический lg, который стоит у каждого второго инженера:

Код: Выделить всё

[alias]
    lg = log --graph --abbrev-commit --decorate \
         --format=format:'%C(bold blue)%h%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' \
         --all
Вывод выглядит так - наша легенда графа держится: узел это коммит, стрелки тут заменяет ASCII-граф слева, ярлыки в скобках это ветки/HEAD/теги:

Код: Выделить всё

$ git lg
* a3f1c08 fix: validate token expiry - Anton (HEAD -> main, origin/main)
* 9b2e441 feat: add refresh endpoint - Maria
| * 7c5d0aa wip: cache layer - Anton (feature/cache)
|/
* 12ab9f0 chore: bump deps - bot
Звёздочка слева - коммит, вертикальные линии - связи коммит-родитель, отметки (HEAD -> main, feature/cache) - ветки и указатель HEAD. Один раз настроил - и больше не открываешь тяжёлый GUI ради взгляда на историю.

Shell-алиасы через восклицательный знак

Если алиас начинается с восклицательного знака, Git не дописывает его к git, а выполняет как команду shell из корня репозитория. Это открывает всё: пайпы, переменные, несколько команд, вызовы внешних утилит.

Код: Выделить всё

[alias]
    cleanup = "!git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d"
    root = "!pwd"
    save = "!git add -A && git commit -m 'WIP savepoint'"
    pushf = "!git push --force-with-lease"
git cleanup удалит все ветки, уже слитые в текущую, кроме самой и main/master. Разберём грабли, на которые тут все наступают: shell-алиас в кавычках, плюс внутри ещё кавычки и звёздочка, которую grep понимает как метасимвол, поэтому её экранируют. Если хочешь принимать аргументы по-человечески, оборачивай в функцию - иначе аргументы прилипнут в самый конец строки, а не туда, где ты ждёшь:

Код: Выделить всё

[alias]
    ignore = "!f() { curl -sL https://www.toptal.com/developers/gitignore/api/$1 >> .gitignore; }; f"
git ignore python докинет питоновские правила в .gitignore. Без функции $1 встал бы в конец и сломал бы вызов curl. Запомни: переменные внутри shell-алиаса оборачивай в функцию f с немедленным вызовом, иначе позиционные аргументы пойдут не туда.

includeIf git: разные личности по каталогу

Вот классическая боль. У тебя один компьютер, на нём рабочие репозитории компании и личные пет-проекты. В рабочих нужен корпоративный email и корпоративный ключ подписи, в личных - твой gmail. Раньше люди вручную дёргали git config user.email в каждом проекте и регулярно забывали. Современное решение 2026 года - условные включения includeIf git, они работают с Git 2.13 и давно стабильны.

Идея: в основном ~/.gitconfig ты подключаешь дополнительный файл по условию - если репозиторий лежит в определённом каталоге. Раскладка такая. Личные проекты держишь в ~/personal/, рабочие в ~/work/. Основной ~/.gitconfig:

Код: Выделить всё

[user]
    name = Anton K
    email = anton.personal@gmail.com

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work

[includeIf "gitdir:~/personal/"]
    path = ~/.gitconfig-personal
Файл ~/.gitconfig-work:

Код: Выделить всё

[user]
    email = anton@bigcorp.io
    signingkey = ~/.ssh/id_ed25519_work.pub
[gpg]
    format = ssh
[commit]
    gpgsign = true
Теперь любой репозиторий внутри ~/work/ автоматически получает корпоративную почту и подпись рабочим SSH-ключом, а всё, что вне - твою личную. Никаких ручных переключений.

Три критичных детали, на которых спотыкаются:
  • Завершающий слеш обязателен. gitdir:~/work/ со слешем матчит каталог и всё, что внутри рекурсивно. Без слеша - только точное совпадение пути, что почти никогда не то, что нужно.
  • Порядок имеет значение. includeIf подмешивается там, где он стоит в файле. Базовый email задавай выше includeIf, чтобы условный его перекрывал, а не наоборот.
  • Условие проверяется по расположению .git, а не по cwd. Есть вариант gitdir/i для регистронезависимого сравнения (полезно на macOS и Windows), и onbranch для условия по имени ветки.
Проверка, что всё подцепилось, делается из рабочего репозитория обычным git config user.email - покажет корпоративный, а из личного gmail. И снова выручает --show-origin: он покажет, из какого именно ~/.gitconfig-work приехало значение.

Несколько SSH-аккаунтов: ~/.ssh/config рядом

includeIf разруливает, какой email и ключ подписи в коммите. Но есть вторая половина задачи - каким SSH-ключом аутентифицироваться на сервере, когда у тебя два аккаунта GitHub (личный и рабочий), а хост у обоих один - github.com. SSH по умолчанию не знает, какой ключ подсунуть. Решается это не в gitconfig, а рядом, в ~/.ssh/config через host-алиасы:

Код: Выделить всё

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes
github-work и github-personal - это выдуманные псевдонимы хоста. Реальный адрес задан в HostName. Теперь клонируешь рабочий репозиторий не через github.com, а через свой алиас:

Код: Выделить всё

$ git clone git@github-work:bigcorp/api.git
$ git clone git@github-personal:anton/blog.git
SSH видит github-work, лезет в config, находит блок и берёт именно рабочий ключ. Ключевая строка - IdentitiesOnly yes: без неё ssh-agent может предложить серверу все ключи подряд, GitHub примет первый подходящий, и ты залогинишься не тем аккаунтом. С IdentitiesOnly используется ровно тот ключ, что прописан.

Связка получается красивая: ~/.ssh/config решает, под кем ты ходишь на сервер, includeIf решает, чьё имя и почта попадут в коммит. Чтобы они не разъезжались, держи рабочие репозитории физически в ~/work/ и клонируй их через github-work - тогда обе системы сработают согласованно.

Настройки качества жизни

Эти ключи не делают ничего магического по отдельности, но вместе превращают Git из сырого инструмента в отлаженный. Пройдёмся по тем, что реально стоит включить.

Код: Выделить всё

[rerere]
    enabled = true
[pull]
    rebase = true
[fetch]
    prune = true
[diff]
    colorMoved = zebra
[help]
    autocorrect = prompt
[core]
    pager = delta
  • rerere.enabled - reuse recorded resolution. Git запоминает, как ты разрулил конфликт слияния, и при повторном таком же конфликте (типично во время долгого rebase) применит решение сам. Бесценно на больших ребейзах.
  • pull.rebase - git pull будет делать rebase вместо merge, история остаётся линейной без мусорных merge-коммитов вида Merge branch main. Альтернатива - значение merges, чтобы сохранять реальные слияния. Без этой настройки свежий Git вообще ругается и просит выбрать стратегию явно.
  • fetch.prune - при fetch чистит локальные remote-tracking ветки, которых уже нет на сервере. Без неё origin/feature-old висит призраком ещё долго после удаления ветки на GitHub.
  • diff.colorMoved - подсвечивает переехавшие блоки кода другим цветом. Когда ты вырезал кусок и вставил в другое место файла, обычный diff покажет это как большое удаление плюс большое добавление; с zebra сразу видно, что код просто переехал.
  • help.autocorrect - реагирует на опечатки. Значение prompt спросит, не имел ли ты в виду status, набрав statsu. Число, например 30, выполнит исправленную команду автоматически через 3 секунды. Лично я предпочитаю prompt - меньше сюрпризов.
  • core.pager - чем листать длинный вывод. По умолчанию less; ниже поставим delta для красивых диффов.
Отдельно про push.autoSetupRemote. Штука удобная: с ней первый git push на новой ветке сам создаёт upstream, и не надо набирать git push -u origin имя-ветки. Но будь честен с собой - это НЕ дефолт даже в 2026 году. На актуальной серии 2.5x (включая 2.54) её надо включать руками:

Код: Выделить всё

[push]
    autoSetupRemote = true
Не верь статьям, где написано, будто это поведение из коробки - проверь свой конфиг.

delta как pager: красивые диффы

delta - сторонняя утилита (ставится через пакетный менеджер: brew, apt, cargo), которая перехватывает вывод diff/blame/grep и рисует его с подсветкой синтаксиса, номерами строк и аккуратными рамками. Базовая настройка:

Код: Выделить всё

[core]
    pager = delta
[interactive]
    diffFilter = delta --color-only
[delta]
    navigate = true
    line-numbers = true
[merge]
    conflictStyle = zdiff3
navigate = true даёт прыжки между файлами по n и N прямо в pager. conflictStyle = zdiff3 (это уже встроенная настройка Git, не delta) показывает в конфликтах общую базу - три блока вместо двух, разбираться в конфликте сильно проще. Если delta не установлена, ничего страшного: убери core.pager = delta, и Git вернётся к less. Альтернативы delta - встроенный less, а из TUI-инструментов экосистемы стоит знать lazygit и gitui, но это уже не про pager.

Мини-лаба: собери свой .gitconfig

Повторяем руками по шагам.
  • 1. Посмотри текущее состояние: git config --list --show-origin --show-scope. Запомни, что уже задано.
  • 2. Добавь четыре простых алиаса: git config --global alias.st status и аналогично co, br, ci. Проверь git st.
  • 3. Добавь граф: открой ~/.gitconfig в редакторе и впиши секцию alias с lg из урока. Выполни git lg в любом репозитории с историей.
  • 4. Сделай личность по каталогу. Создай ~/work/ и ~/personal/. В ~/.gitconfig добавь два блока includeIf со слешами на конце. Заведи ~/.gitconfig-work с рабочим email. Склонируй любой репозиторий в ~/work/ и проверь git config user.email - должен быть рабочий.
  • 5. Настрой multi-SSH. В ~/.ssh/config добавь host-алиас github-work с IdentitiesOnly yes. Проверь связь: ssh -T git@github-work.
  • 6. Включи качество жизни: rerere.enabled, pull.rebase, fetch.prune, diff.colorMoved, help.autocorrect, push.autoSetupRemote. Перечитай git config --list и убедись, что всё на месте.
Готовый профессиональный .gitconfig

Забирай целиком, подставь свои имя/почту и каталоги:

Код: Выделить всё

[user]
    name = Anton K
    email = anton.personal@gmail.com

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work

[init]
    defaultBranch = main

[core]
    pager = delta
    editor = nvim

[pull]
    rebase = true
[fetch]
    prune = true
[push]
    autoSetupRemote = true
[rerere]
    enabled = true
[help]
    autocorrect = prompt

[diff]
    colorMoved = zebra
    algorithm = histogram
[merge]
    conflictStyle = zdiff3

[interactive]
    diffFilter = delta --color-only
[delta]
    navigate = true
    line-numbers = true

[alias]
    st = status -sb
    co = checkout
    sw = switch
    br = branch
    ci = commit
    last = log -1 HEAD --stat
    unstage = reset HEAD --
    amend = commit --amend --no-edit
    aliases = config --get-regexp ^alias\\.
    lg = log --graph --abbrev-commit --decorate \
         --format=format:'%C(bold blue)%h%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' \
         --all
    cleanup = "!git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d"
    pushf = "!git push --force-with-lease"
Заметь: init.defaultBranch = main выставлен вручную - в ванильном Git на 2026 ветка по умолчанию всё ещё master, встроенным дефолтом main станет только в 3.0. И ещё я подложил sw = switch рядом с co - git switch стабилен с 2.51, привыкай к нему вместо checkout.

Контрольные вопросы
  • 1. Чем shell-алиас (с восклицательным знаком) отличается от обычного, и зачем в нём оборачивать тело в функцию f?
  • 2. Почему в gitdir:~/work/ завершающий слеш критичен, и по чему именно проверяется условие includeIf - по текущему каталогу или по расположению .git?
  • 3. Что делает IdentitiesOnly yes в ~/.ssh/config и какая беда случается без неё при двух аккаунтах GitHub?
  • 4. Правда ли, что push.autoSetupRemote включён по умолчанию в 2026? Как проверить на своей машине?
Итог

Хороший .gitconfig - это разовая инвестиция с пожизненной отдачей. Алиасы режут рутину, includeSif раскладывает личности по каталогам без ручных переключений, ~/.ssh/config с host-алиасами разводит несколько аккаунтов по ключам, а настройки качества жизни (rerere, prune, colorMoved, delta) делают повседневную работу тише и приятнее. Главный навык на будущее - git config --show-origin: когда что-то ведёт себя странно, ты всегда знаешь, какой файл и какой уровень виноват.
👍2 ❤️2 🔥 😄 🤔
Аватара пользователя
redis_maker
Сообщения: 1
Зарегистрирован: 22 май 2026, 03:47

Re: Псевдонимы и кастомизация .gitconfig

Сообщение redis_maker »

А я думал autoSetupRemote давно дефолт, везде так пишут. Проверил git config - и правда пусто. Спасибо что предупредил, добавил руками.
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
madpanic
Сообщения: 1
Зарегистрирован: 19 май 2026, 15:33

Re: Псевдонимы и кастомизация .gitconfig

Сообщение madpanic »

Затык был именно в SSH: два аккаунта, один github.com, постоянно ловил Permission denied. IdentitiesOnly yes плюс host-алиас все починили. Огонь урок.
👍 ❤️1 🔥 😄 🤔2
Ответить
← Предыдущая глава
Вспомогательные команды: clean, mv, rm, restore
Следующая глава →
Хуки Git: автоматизация на клиенте и сервере

Все главы курса «Git профессионально: от первого коммита до внутреннего устройства»

Поделиться темой: ✈ Telegram VK
  • Похожие темы
Похожие запросы: Настройка Git: git config и .gitconfig

Вернуться в «Git профессионально: от первого коммита до внутреннего устройства»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость