Git pre-push для предотвращения слияния - PullRequest
0 голосов
/ 16 января 2019

я сделал этот bash-скрипт для своих git-хуков, чтобы избежать слияния по ошибке.

На работе мы используем git-extension, и оно предварительно заполняет имя ветки, если вы забыли добавить префикс имени ветки к refs / for или refs / drafts, тогда ваши коммиты объединяются в удаленном репо, минуя проверку кода.

Это может произойти только с людьми с правом слияния. но иногда кто-то с правом слияния совершит эту ошибку.

#!/bin/sh

if [[ `grep 'refs/for'` ]]; then 
  echo "push to refs/for/ authorized"
elif [[ `grep 'refs/drafts/'` ]]; then
  echo "push to refs/drafts/ authorized"
else
  echo "PUSH DENIED, MERGE DETECTED, please merge using gerrit 'submit' button only"
  exit 1
fi

если я нажму refs/for/v1.1.x, получится push to refs/for/ authorized

однако, если я нажму refs/drafts/v1.1.x, я получу PUSH DENIED, MERGE DETECTED, please merge using gerrit 'submit' button only

Как это возможно, синтаксис условия точно такой же.

Спасибо.

1 Ответ

0 голосов
/ 16 января 2019

Как заметил Энтони Соттил , ваша первая команда grep читает все входные данные, проверяя refs/for.Ваш второй grep читает оставшиеся данные;так как ваш первый прочитал все ввода, ничего не осталось.Поэтому второй никогда ничего не находит.

С этим можно справиться разными способами.Одним из них является копирование стандартного ввода во временный файл, который вы можете прочитать несколько раз.Другой способ - структурировать ваш хук так, чтобы вы читали входные данные только один раз, проверяя каждую строку для каждого условия.Этот второй метод, очевидно, более эффективен, хотя эта «очевидность» немного иллюзорна, в зависимости от деталей, которые я не собираюсь здесь раскрывать.

В любом случае, я бы написал так:

#! /bin/sh

summary_status=0     # assume all OK initially
while read lref lhash rref rhash; do
    case $rref in
    refs/for/*|refs/draft/*) echo "push to $rref ok";;
    *) echo "push to $rref not ok"; summary_status=1;;
    esac
done
exit $summary_status

Этот вариант не требует функций bash (следовательно, /bin/sh вместо /bin/bash в строке #!);если вы измените его на тот, который имеет, обязательно измените строку #!.Он читает входные данные ровно один раз.Он также проверяет, что вы не запустили, например:

git push remote master:refs/for/master develop

, что позволит существующий сценарий (поскольку один в порядке, а другой нет).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...