Предотвратить коммиты в основной ветке

84

(Для простоты) у меня есть masterветка и devв моем репозитории Git. Я хочу, чтобы masterветка всегда работала, поэтому вся моя работа должна выполняться в devветке.

Однако, когда я объединяю свои изменения с помощью --no-ffслияния, я обычно остаюсь в masterветке и просто продолжаю работать в ней (потому что я забываю проверить свою devветку).

Могу ли я установить правило для masterветки, в котором говорится, что я не могу выполнять коммиты и слияния с быстрой перемоткой вперед, но только --no-ffслияния из другой ветки?

Это должно работать для частных репозиториев (например, не GitHub и BitBucket).

Расмус Бёкгаард
источник
4
"перемотка вперед" - это не вещь. Коммиты - это просто коммиты, git commitсоздание новых, быстрой перемотки вперед не происходит. Похоже, вы просто хотите запретить обычные коммиты, когда текущая ветка - masterи в этом случае загляните в pre-commitловушку.
torek

Ответы:

154

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

  1. Зайдите в свой репозиторий.
  2. Создайте файл .git / hooks / pre-commit со следующим содержимым:

    #!/bin/sh
    
    branch="$(git rev-parse --abbrev-ref HEAD)"
    
    if [ "$branch" = "master" ]; then
      echo "You can't commit directly to master branch"
      exit 1
    fi
    
  3. Сделайте его исполняемым (не требуется в Windows ):

    $ chmod +x .git/hooks/pre-commit
    

Чтобы отключить быструю перемотку вперед, вы также должны добавить следующую опцию в ваш .git / config файл:

[branch "master"]
    mergeoptions = --no-ff

Если вы хотите также защитить главную ветку на своем пульте дистанционного управления, проверьте этот ответ: Как ограничить доступ к главной ветке на git

qzb
источник
Это похоже на то, что мне нужно - это работает и в Windows?
Rasmus Bækgaard 08
2
@ RasmusBækgaard, да, будет: сценарий bash для ловушки будет интерпретироваться Git bash, включенным в Git для Windows. (Вам просто не нужен шаг chmod)
VonC
примечание: вы также можете запретить себе нажимать на удаленную masterветку в крючке предварительного нажатия. пример
Аарон Хоффман
4
Отлично, для тех, кто ищет способ добавить эти правила или другие хуки git в репозиторий проекта, проверьте этот простой пакет npm: github.com/kilianc/shared-git-hooks , потому что вы не можете включить ничего, что находится под Каталог .git в репозиторий.
Джордж Димитриадис,
9
кроме того, это только для нашего локального репозитория git, как мы можем обеспечить соблюдение правил в разных репозиториях git для всех разработчиков, не заставляя их вручную изменять содержимое каталога .git?
Александр Миллс
13

Для этого вы можете использовать утилиту предварительной фиксации . Он имеет встроенный no-commit-to-branchкрючок, который можно использовать для предотвращения коммитов в одну или несколько веток.

Настроить

Базовый процесс настройки:

  • Установите с помощью pip или brew (инструкции на https://pre-commit.com/#install )
  • Создайте .pre-commit-config.yamlфайл в корне вашего проекта (см. Ниже первый черновик)
  • Установите хуки в конфигурацию git, запустив pre-commit install.

Базовый конфиг для защиты веток

Вот базовая конфигурация, которая включает только no-commit-to-branchперехватчик:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master']

Если вы хотите защитить несколько веток, вы можете включить несколько --branchаргументов в список аргументов:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master', '--branch', 'staging']

Разве это не перебор?

У предварительной фиксации есть много других встроенных хуков, а также большая коллекция созданных сообществом хуков , которые изменят способ очистки и проверки ваших коммитов. Я упоминаю об этом потому, что, хотя этот инструмент может быть излишним для простого предотвращения коммитов в защищенную ветку, у него есть много других функций, которые делают его неотразимым и простым дополнением к любому проекту git.

JGC
источник
7

Возможно, имеет смысл установить его глобально через

git config --global core.hooksPath ~/githooks

и переместив этот pre-commitфайл в этот каталог

Мишель Самиа
источник
Что делать, если у меня несколько репозиториев - не повлияет ли это на все?
Rasmus Bkgaard
1
и это то, что вы можете делать в большинстве случаев
Мишель
Допустим, у меня есть этот странный проект, где они переименованы masterв Production- можно ли сделать исключения?
Rasmus Bækgaard 08
вы можете использовать оператор or в bash, чтобы указать больше веток, которые вы хотите защитить на стороне клиента,
Мишель