Как запретить push в ветку `main` с помощью хука?

Для запрета `push` в ветку `main` с помощью хука, необходимо создать файл `pre-receive` в директории `.git/hooks/` репозитория на сервере. Внутри файла `pre-receive` разместить скрипт, который проверяет, не пытается ли кто-то отправить изменения в ветку `main`. Если да, то скрипт должен завершиться с ненулевым кодом возврата и сообщением об ошибке. Пример скрипта `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 запрещен. Используйте pull request." >&2
      exit 1
    fi
  done
  
Убедитесь, что файл `pre-receive` имеет права на исполнение: `chmod +x .git/hooks/pre-receive`.

Запретить push в ветку main с помощью хука можно, используя хук pre-receive на стороне сервера (репозитория). Вот как это сделать:

  1. Подключитесь к серверу, где расположен ваш Git репозиторий. Вам понадобится доступ к директории .git репозитория.

  2. Перейдите в директорию .git/hooks. Если директории hooks не существует, создайте её.

    cd .git/hooks
  3. Создайте файл pre-receive. Если он уже существует, убедитесь, что он исполняемый.

    touch pre-receive
    chmod +x pre-receive
  4. Добавьте следующий скрипт в файл 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
    
  5. Разберем скрипт:

    • #!/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 разрешен.
  6. Сделайте файл pre-receive исполняемым. Это необходимо для того, чтобы Git мог его выполнить.

    chmod +x pre-receive

Альтернативные подходы:

  • Использование GUI (GitLab, GitHub, Bitbucket): Многие платформы предоставляют интерфейс для настройки правил ветвления, которые позволяют запретить push в определенные ветки без написания хуков. Это часто проще в управлении, особенно в командной среде.
  • Другие языки скриптов: Вместо bash можно использовать другие скриптовые языки, такие как Python или Ruby. Однако убедитесь, что интерпретатор установлен на сервере и доступен для выполнения скрипта.

Важно: Хуки выполняются на сервере. Клиент не может обойти эти правила. Все push-операции, которые пытаются внести изменения в ветку main, будут отклонены сервером.

0