#!/bin/bash
  while read oldrev newrev refname
  do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "$branch" = "main" ]; then
      echo "Push в ветку main запрещен. Используйте pull request." >&2
      exit 1
    fi
  done
  Запретить push в ветку main с помощью хука можно, используя хук pre-receive на стороне сервера (репозитория). Вот как это сделать:
Подключитесь к серверу, где расположен ваш Git репозиторий. Вам понадобится доступ к директории .git репозитория.
Перейдите в директорию .git/hooks. Если директории hooks не существует, создайте её.
cd .git/hooksСоздайте файл pre-receive.  Если он уже существует, убедитесь, что он исполняемый.
touch pre-receive
chmod +x pre-receiveДобавьте следующий скрипт в файл pre-receive:
#!/bin/bash
while read oldrev newrev refname; do
  branch=$(git rev-parse --symbolic --abbrev-ref $refname)
  if [[ "$branch" == "main" ]]; then
    echo "Push в ветку main запрещен!"
    exit 1
  fi
done
exit 0
Разберем скрипт:
#!/bin/bash: Указывает, что это bash скрипт.while read oldrev newrev refname:  Читает стандартный ввод, предоставляемый Git. Для каждой ветки, в которую происходит push, он получает старый ревизионный номер (oldrev), новый ревизионный номер (newrev) и полное имя ссылки (refname).branch=$(git rev-parse --symbolic --abbrev-ref $refname): Извлекает имя ветки из refname.  Например, если refname равно refs/heads/main, то branch станет main.if [[ "$branch" == "main" ]]:  Проверяет, является ли имя ветки main.echo "Push в ветку main запрещен!": Если имя ветки main, выводит сообщение об ошибке.exit 1: Выход из скрипта с кодом 1, что сигнализирует Git о том, что push должен быть отклонен.exit 0: Выход из скрипта с кодом 0, что означает, что push разрешен.Сделайте файл pre-receive исполняемым.  Это необходимо для того, чтобы Git мог его выполнить.
chmod +x pre-receiveАльтернативные подходы:
Важно: Хуки выполняются на сервере.  Клиент не может обойти эти правила.  Все push-операции, которые пытаются внести изменения в ветку main, будут отклонены сервером.