Два аккаунта Git на одном ПК: как настроить и не запутаться
Два аккаунта Git на одном ПК
У вас есть личный аккаунт на GitHub для пет-проектов и рабочий — на GitLab компании (или второй на GitHub). А компьютер один. По умолчанию Git хранит имя и email в единственном глобальном файле ~/.gitconfig, поэтому без настройки рано или поздно случится одно из двух:
- рабочий коммит окажется подписан личной почтой (или наоборот);
- Git предложит серверу не тот SSH-ключ и получите
Permission denied (publickey).
Проблема решается тремя вещами:
- Отдельная папка для рабочих проектов. Всё рабочее живёт только в ней, например в
~/dev/work. - Отдельный SSH-ключ для каждого аккаунта. Файл
~/.ssh/configсообщает SSH, какой ключ для какого сервера. - Условное включение конфига (
includeIf). В основном~/.gitconfigпрописан личный профиль, а для рабочей папки подключается дополнительный~/.gitconfig-work, который переопределяет имя и email.
Настраивается один раз, дальше Git переключает личность сам — по пути к папке репозитория.
Все команды выполняются в терминале (в Windows — в Git Bash). Запись ~ означает домашний каталог: в Windows это C:\Users\<имя_пользователя>, в Linux/macOS — /home/<имя_пользователя> или /Users/<имя_пользователя>.
Шаг 1. Посмотрите, что настроено сейчас
git config --global user.name
git config --global user.emailПолезная команда для отладки — покажет все настройки и файл, из которого взята каждая:
git config --list --show-originШаг 2. Заведите отдельную папку для рабочих проектов
mkdir -p ~/dev/workГлавное правило всей схемы: рабочие репозитории клонируются только в эту папку. Личные могут лежать где угодно.
Шаг 3. Создайте два SSH-ключа
По одному ключу на аккаунт:
# личный ключ
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_personal -C "ivan@example.com"
# рабочий ключ
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C "i.ivanov@company.com"Каждая команда создаёт пару файлов: приватный ключ (id_ed25519_personal) и публичный (id_ed25519_personal.pub). Комментарий после -C — просто пометка, удобно указывать почту аккаунта. На вопрос про парольную фразу (passphrase) можно нажать Enter, но лучше её задать: приватный ключ без пароля — это доступ ко всем вашим репозиториям для любого, кто получит файл.
Шаг 4. Добавьте публичные ключи в аккаунты
Выведите публичный ключ и скопируйте его целиком:
cat ~/.ssh/id_ed25519_personal.pubДальше — в настройки аккаунта:
- GitHub: Settings → SSH and GPG keys → New SSH key;
- GitLab: Preferences → SSH Keys → Add new key.
Для рабочего ключа (id_ed25519_work.pub) повторите то же самое в рабочем аккаунте.
В аккаунты добавляются только файлы с расширением .pub — публичные ключи. Приватные ключи (без расширения) никогда и никому не передавайте.
Шаг 5. Настройте ~/.ssh/config
Создайте или отредактируйте файл ~/.ssh/config так, чтобы каждому серверу соответствовал свой ключ:
# Личный аккаунт — GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
# Рабочий аккаунт — GitLab компании
Host gitlab.company.com
HostName gitlab.company.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yesПроверьте, что ключи подхватились:
ssh -T git@github.com
ssh -T git@gitlab.company.comGitHub ответит Hi <username>!, GitLab — Welcome to GitLab, @<username>!. Убедитесь, что в приветствии указано именно нужное имя аккаунта.
Строка IdentitiesOnly yes заставляет SSH предлагать серверу только ключ из IdentityFile. Без неё SSH перебирает все найденные ключи, и сервер может принять первый попавшийся — то есть «залогинить» не тот аккаунт. Это самая частая причина путаницы с ключами.
Шаг 6. Пропишите личный профиль в ~/.gitconfig
Откройте ~/.gitconfig и добавьте личные данные и условное включение рабочего конфига:
[user]
name = Ivan Ivanov
email = ivan@example.com
# для репозиториев из папки ~/dev/work подключается рабочий профиль
[includeIf "gitdir:~/dev/work/"]
path = .gitconfig-workРазберём условие includeIf:
gitdir:~/dev/work/— условие срабатывает, когда репозиторий находится в этой папке. Путь пишется с прямыми слэшами (даже в Windows);~— домашний каталог. Можно указать и полный путь:gitdir:C:/Users/<имя_пользователя>/dev/work/;- конечный
/важен: с ним условие охватывает саму папкуworkи все её подпапки на любой глубине; path = .gitconfig-work— путь к файлу с рабочим профилем. Относительный путь считается от файла, в котором написанincludeIf, то есть от домашнего каталога.
В этот же файл складывайте всё общее: алиасы, цвета, настройки push — они будут действовать для обоих аккаунтов.
Шаг 7. Создайте ~/.gitconfig-work
Создайте в домашнем каталоге файл ~/.gitconfig-work с рабочими данными:
[user]
name = Ivan Ivanov
email = i.ivanov@company.comЗдесь — только то, что отличается от личного профиля: имя и почта. Всё остальное рабочие репозитории унаследуют от основного конфига автоматически.
Шаг 8. Проверьте переключение
Склонируйте рабочий репозиторий в рабочую папку и посмотрите, каким email Git подписывает коммиты:
cd ~/dev/work
git clone git@gitlab.company.com:team/project.git
cd project
git config user.email
# i.ivanov@company.comВ любом репозитории вне рабочей папки та же команда вернёт личную почту. Финальная проверка — пустой тестовый коммит:
git commit --allow-empty -m "test identity"
git log --format='%an <%ae>' -1
# Ivan Ivanov <i.ivanov@company.com>Если в рабочей папке автор — рабочая почта, а вне её — личная, всё настроено верно.
Если оба аккаунта на одном хостинге
Когда личный и рабочий аккаунты лежат на одном сервере (например, оба на GitHub), правила «какой хост — такой ключ» уже недостаточно: у сервера одно имя. Тогда в ~/.ssh/config для второго аккаунта заводят псевдоним:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
Host github-work # псевдоним для рабочего аккаунта
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yesИ рабочие репозитории клонируют через этот псевдоним — он заменяет имя хоста в адресе:
cd ~/dev/work
git clone git@github-work:my-company/project.gitПереключение профиля по папке (includeIf) работает точно так же, как описано выше.
Подпись коммитов по SSH (опционально)
GitHub и GitLab умеют проверять подпись коммитов и помечать их значком «Verified». Если коротко: подписываются теми же SSH-ключами, что и авторизация, отдельный GPG-ключ не нужен.
Добавьте в основной ~/.gitconfig:
[user]
signingkey = ~/.ssh/id_ed25519_personal.pub
[commit]
gpgsign = true
[gpg]
format = ssh
[gpg "ssh"]
allowedSignersFile = ~/.ssh/allowed_signers
# в Windows может понадобиться явный путь к ssh-keygen:
# program = C:/Windows/System32/OpenSSH/ssh-keygen.exeИ укажите рабочий ключ подписи в ~/.gitconfig-work:
[user]
name = Ivan Ivanov
email = i.ivanov@company.com
signingkey = ~/.ssh/id_ed25519_work.pubФайл ~/.ssh/allowed_signers нужен, чтобы Git мог проверять подписи локально — внесите в него оба ключа:
echo "ivan@example.com namespaces=\"git\" $(cat ~/.ssh/id_ed25519_personal.pub)" >> ~/.ssh/allowed_signers
echo "i.ivanov@company.com namespaces=\"git\" $(cat ~/.ssh/id_ed25519_work.pub)" >> ~/.ssh/allowed_signersПроверка подписи последнего коммита:
git log --show-signature -1Как не запутаться
- Рабочие репозитории — только в рабочей папке. Вся схема переключения держится на этом одном правиле.
- Перед первым коммитом в новый репозиторий бросьте взгляд на
git config user.email— одна секунда, а нервы сберегает. - Заведите алиас, который показывает текущую личность:
[alias]
whoami = "!git config user.name && git config user.email"git whoami- Репозиторий оказался не в той папке? Просто перенесите его в рабочую — Git при следующем коммите возьмёт правильный профиль. Либо пропишите данные локально:
git config user.email "i.ivanov@company.com"без--globalдействует только на этот репозиторий. - Последний коммит ушёл не от того автора? Исправьте настройки и выполните
git commit --amend --reset-author --no-edit— коммит будет переписан актуальными данными. - Непонятно, откуда взялась та или иная настройка?
git config --list --show-originпокажет файл-источник для каждой строки.
Как итог: один раз настроили ~/.ssh/config с двумя ключами и includeIf в .gitconfig — и дальше Git сам знает, кем вы считаетесь в каждой папке. Единственное, что требуется от вас, — держать рабочие проекты в отведённом для них месте.