Что делать неизвестным в вашем git репозитории
Всем привет! Предлагаю взглянуть на проблему, связанную с появлением коммитов от «неизвестных» пользователей в вашем git репозитории. Такое может возникнуть, если один разработчик будет использовать несколько разных git конфигов. Расскажу, какие есть варианты избежать похожую ситуацию.
Контроль git config в проекте
Для добавления коммита в Git репозиторий требуется адрес электронной почты и имя пользователя. Нередко бывают случаи, когда в рабочий репозиторий «улетают» коммиты с личными настройками. Таким образом, мы получаем коммиты от одного человека, но пользователь в git выглядит и подписан по-разному. В таких случаях часто не отображаются аватарки и имя не соответствует зарегистрированному пользователю. В рабочем репозитории важно, чтобы имя и адрес электронной почты пользователя были указаны корректно.
Давайте разберемся в причинах возникновения подобных ситуаций. У многих разработчиков глобально установлен личный git config, и при клонировании или создании проектов они просто забывают или не знают, как его поменять. Также бывают ситуации, когда разработчик в понедельник, а возможно и в любой другой день, после работы или во время нее, работает над своим pet-проектом, переключается на рабочий проект и создает коммиты с личными данными. Бывает и наоборот, когда люди, имея глобально рабочие конфиги, вносят изменения в большие open source проекты и публикуют коммиты с рабочими данными.
Некоторые не видят в этом проблем, но они есть:
Электронная почта вашей компании и настоящее имя будут находится в публичных репозиториях.
Данные могут использоваться в различных фишинг атаках против вас.
Ваша команда будет видеть ваш никнейм вместо настоящего имени в истории комитов.
Ну и самое главное — это непрофессионально.
Пример двух коммитов от одного разработчика с двумя разными git конфигами
Давайте рассмотрим варианты решения описанной проблемы.
Первый вариант — это применение глобального конфига на машине разработчика. Для этого достаточно установить глобально личный конфиг, а для рабочих репозиториев использовать локально рабочий.
git config --global user.email "myname@mail.com" git config --global user.name "myname"
git config user.email "company@companydomain.com" git config user.name "Firstname Lastname"
Это решение зависит от внимательности каждого из разработчиков и не исключает человеческий фактор.
Если вы используете для работы с Git такой веб-инструмент как GitLab, то у меня есть для вас простое решение. GitLab позволяет настраивать в репозитории правила отправки коммитов Push rules. Все что вам нужно сделать:
Открыть Menu > Projects и найти свой проект.
Далее выбрать Settings > Repository.
Развернуть Push rules.
В поле Commit author’s email впишите регулярное выражение на проверку домена почты. Например, для почты с доменом @nlmk.com регулярное выражение будет выглядеть так
@nlmk.\S+$
. Более подробно ознакомиться с синтаксисом регулярных выражений можно тут.Сохраните изменения.
Push правило для проверки домена почты в git config
Если вдруг в вашем конфиге будет указана почта с доменом, не подходящим под регулярное выражение, то при пуше изменений в ветку возникнет ошибка.
Ошибка при проверки почты регулярным выражением
Как итог, вы гарантируете, что в ваш рабочий репозиторий не будут добавлены коммиты пользователями с почтой, не соответствующей вашему домену.
Также одним из решений могут послужить git-хуки. В данном случае это решение подходит не только для gitlab, но и для других популярных git репозиториев. Git предоставляет возможность запуска пользовательских скриптов в случае возникновения определённых событий, таких как push, commit, merge и т.д. Для работы с Git хуками я буду использовать husky.
#Устанавливаем husky
npm install husky --save-dev #Включаем Git хуки
npx husky install
#Добавляем скрипт в package.json
npm set-script prepare "husky install" #Создаем хук
npx husky add .husky/pre-commit "npm test"
В созданном файле pre-commit
прописываем bash-скрипт:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
#Регулярное выражение для проверки почты
MAIL_REGEX="^[[:alnum:]._%+-]+@gmail+\.[[:alpha:].]{2,4}$"
EMAIL=$(git config user.email)
if [[ $EMAIL =~ $MAIL_REGEX ]];
then
echo "текущая почта '$EMAIL' совпадает с '$MAIL_REGEX'" else
echo "текущая почта '$EMAIL' не совпадает с '$MAIL_REGEX'" exit 1
fi
При несовпадении почты конфига с регулярным выражением вы увидите следующую ошибку:
В данном решении есть плюсы и минусы. Преимущество данного решения перед предыдущим — это возможность проверить не только почту, но и имя пользователя.
Однако стоит заметить, что этот код выполняется на стороне клиента, и при желании можно отправить коммит в репозиторий без проверки.
С версии 2.9 Git предлагает возможность глобального совместного использования хуков между репозиториями. Этот вариант исключает дублирование хуков в каждом репозитории.
Для применения глобальных хуков сначала создадим для них папку и назовем githooks
. Далее глобально настроим Git, чтобы использовать созданную папку в качестве папки для хранения глобальных хуков:
#Создадим директории
mkdir -p ~/githooks/_git/hooks/
#Установим путь для хранения глобальных хуков
git config --global core.hooksPath ~/githooks/_git/hooks/
Добавим следующий код в глобальный конфиг Git:
cat ~/.gitconfig
...
[user]
name = Nickname or Fullname
email = personal_or_business@mail.com [core]
hooksPath = ~/githooks/_git/templates/hooks/
...
Проверим адрес электронной почты, который установлен в репозитории. Тут стоит отметить, что скрипт зависит от ваших методов работы и потребностей.
Предположим, что ваши личные репозитории расположены тут — ~/projects/personal
, а рабочие тут — ~/projects/business
. Тогда bash-скрипт для проверки адреса электронной почты перед коммитом будет выглядеть так:
#!/bin/sh PWD=`pwd`
#Проверяем, содержит ли текущий путь "business” if [[ $PWD == *"business"* ]]
then
EMAIL=$(git config user.email)
MAIL_REGEX="^[[:alnum:]._%+-]+@gmail+\.[[:alpha:].]{2,4}$"
#Проверяем почту с помощью регулярного выражения
if [[ $EMAIL =~ $MAIL_REGEX ]]
then
echo "";
else
echo "данная почта не подходит к этому репозиторию"; echo ''
#Если что-то не так, выходим из скрипта с ошибкой exit 1;
fi;
fi;
Настройка глобального git хука и продумывание алгоритма полностью зависит от вашей структуры работы, потребностей и фантазии. Данное решение работает, но проблема в том, что оно уникальное для каждого разработчика.
В моем случае, в компании мы храним правила ведения проекта в readme и в onboarding документах, с которых начинают знакомство с нашими проектами все разработчики. Правила содержат инструкцию о добавлении локальных конфигов в проектах. Также во всех наших GitLab репозиториях добавлено правило проверки почты пользователя. Это полностью избавило нас от «анонимных» коммитов в рабочих репозиториях.