Всем привет! Предлагаю взглянуть на проблему, связанную с появлением коммитов от «неизвестных» пользователей в вашем git репозитории. Такое может возникнуть, если один разработчик будет использовать несколько разных git конфигов. Расскажу, какие есть варианты избежать похожую ситуацию.

Контроль git config в проекте

Для добавления коммита в Git репозиторий требуется адрес электронной почты и имя пользователя. Нередко бывают случаи, когда в рабочий репозиторий «улетают» коммиты с личными настройками. Таким образом, мы получаем коммиты от одного человека, но пользователь в git выглядит и подписан по-разному. В таких случаях часто не отображаются аватарки и имя не соответствует зарегистрированному пользователю. В рабочем репозитории важно, чтобы имя и адрес электронной почты пользователя были указаны корректно.

Давайте разберемся в причинах возникновения подобных ситуаций. У многих разработчиков глобально установлен личный git config, и при клонировании или создании проектов они просто забывают или не знают, как его поменять. Также бывают ситуации, когда разработчик в понедельник, а возможно и в любой другой день, после работы или во время нее, работает над своим pet-проектом, переключается на рабочий проект и создает коммиты с личными данными. Бывает и наоборот, когда люди, имея глобально рабочие конфиги, вносят изменения в большие open source проекты и публикуют коммиты с рабочими данными.

Некоторые не видят в этом проблем, но они есть:

  1. Электронная почта вашей компании и настоящее имя будут находится в публичных репозиториях.

  2. Данные могут использоваться в различных фишинг атаках против вас.

  3. Ваша команда будет видеть ваш никнейм вместо настоящего имени в истории комитов.

  4. Ну и самое главное — это непрофессионально.

Пример двух коммитов от одного разработчика с двумя разными git конфигами
Пример двух коммитов от одного разработчика с двумя разными 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. Все что вам нужно сделать:

  1. Открыть Menu > Projects и найти свой проект.

  2. Далее выбрать Settings > Repository.

  3. Развернуть Push rules.

  4. В поле Commit author's email впишите регулярное выражение на проверку домена почты. Например, для почты с доменом @nlmk.com регулярное выражение будет выглядеть так @nlmk.\S+$ . Более подробно ознакомиться с синтаксисом регулярных выражений можно тут.

  5. Сохраните изменения.

Push правило для проверки домена почты в git config
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 репозиториях добавлено правило проверки почты пользователя. Это полностью избавило нас от «анонимных» коммитов в рабочих репозиториях.

Ссылки по теме

Комментарии (4)


  1. darkxanter
    30.06.2022 13:52
    +34

    В ~/.config/git/config можно прописать include секции и не нужно в каждом проекте руками прописывать настройки:

    [include]
    	path = config.personal
    
    [includeIf "gitdir:**/work/**/.git"]
    	path = config.work

    config.personal:

    [user]
    	email = user@gmail.com

    config.work:

    [user]
    	email = user@company.com


    1. Naughty1905 Автор
      30.06.2022 13:59
      +1

      Согласен, можно, но в конце статьи описал решение по смыслу такое же, разве нет?.


      1. darkxanter
        30.06.2022 14:02
        +4

        В статье описаны проверки через хуки, ведь настроить почту все равно придется в конкретном проекте. А если указать в конфиге что по такому пути лежат рабочие проекты, то будет использоваться рабочий email и в хуках эта проверка пройдет.


        1. Naughty1905 Автор
          30.06.2022 14:17
          +2

          Согласен, вообще тоже отличный вариант и отчасти более простой. Хотя тут тоже все на стороне разработчика реализовано и лишние проверки никогда не помешают.