Перехватчик GIT для предотвращения отправки экспериментальной ветки в релиз или основную ветку

У нас есть три основные ветви в нашем рабочем процессе.

TEST (экспериментальный), RELEASE (функции, которые появятся в следующем выпуске) и MASTER (только выпущенные)

Мы берем ветки функций из RELEASE, сначала объединяем ветки функций в TEST и, если они в порядке, объединяем эти утвержденные ветки функций в RELEASE.

Моя проблема: поскольку ветка TEST содержит некоторые коммиты/функции, которые мы никогда не будем выпускать, мы не хотим, чтобы она была объединена в RELEASE или MASTER по ошибке (или намеренно).

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

Поэтому, вероятно, лучше предотвратить обновления ссылок MASTER или RELEASE ветки в основном репозитории (путем отправки в источник), когда новая ссылка содержит определенный идентификатор фиксации ветки TEST в своем журнале фиксации.

Поэтому я сделаю конкретную фиксацию только для ветки TEST и запишу ее идентификатор фиксации.

Всякий раз, когда кто-то хочет нажать на главную или релизную ветку, я проверю, обновит ли этот толчок мои refs/heads/master или refs/heads/RELEASE до фиксации ref, которая содержит этот неверный идентификатор фиксации в своей истории, и прервется.

Поскольку я не мастер BASH или GIT, есть ли у кого-нибудь такой хук обновления, который мы можем применить к нашему основному репозиторию?


person Volkan Ceylan    schedule 14.11.2012    source источник


Ответы (2)


Вот хук обновления, который должен работать для этого. Вы можете указать коммиты, которые не должны быть разрешены в вашей ветке RELEASE или MASTER, присвоив им теги, такие как forbidden/junk или forbidden/debugging. Если обнаружен запрещенный коммит, имя тега будет включено в сообщение об отклонении.

refname="$1"
oldrev="$2"
newrev="$3"
case "$refname" in
  refs/heads/RELEASE|refs/heads/MASTER)
    for forbidden in $(git tag -l 'forbidden/*'); do
      if [ $(git merge-base "$forbidden" $newrev) = $(git rev-parse "$forbidden") ]; then
        echo "Push to $refname contains commit $forbidden" >&2
        exit 1
      fi
    done
    ;;
esac
exit 0

Обратите внимание: если у вас есть ветка, содержащая несколько проблемных коммитов, вы должны создать тег forbidden для самого раннего из них, а не только для последнего коммита в серии. Таким образом, если история, подобная следующей, где B, C и D запрещены, просто пометка D как запрещенная не предотвратит слияние E и принесет с собой B.

A---B----C----D
     \
      ---E
person qqx    schedule 14.11.2012
comment
Спасибо, выглядит очень многообещающе, я протестирую и дам вам знать. чтобы уточнить, я должен применить это к основному репо, верно? и как вы думаете, у меня возникнут проблемы, такие как «платформы», указанные в другом ответе, если я только сольюсь с TEST и никогда не сольюсь обратно или не отделюсь от TEST? - person Volkan Ceylan; 15.11.2012
comment
Да, это должно быть установлено как хук update в главном репозитории. Я не ожидаю проблем из-за того, что ваша ветка TEST получает много слияний, но сама никогда не сливается. - person qqx; 15.11.2012
comment
что, если я помечу очень старую фиксацию в ветке TEST (например, фиксация слияния, такая как объединенная «ветка feature-abcd в TEST»), которая не находится в ветке RELEASE. Придется ли мне по-прежнему отмечать новые коммиты (обычно они просто коммиты слияния) как запрещенные, как вы написали? - person Volkan Ceylan; 15.11.2012
comment
Было бы хорошо пометить только первый из серии запрещенных коммитов, более поздние коммиты будут содержать его, что предотвратит втягивание всей серии. Я обновил ответ, чтобы лучше отразить это. - person qqx; 15.11.2012
comment
Можно ли использовать эту стратегию в сочетании с BitBucket (или GitHub или подобным сервисом)? - person Patrick Sanan; 03.09.2014
comment
@TheNobleSunfish Вероятно, нет, для этого требуется установить скрипт на сервер git, и я не знаю ни одного хостинг-сайта, который это позволяет. Вы можете использовать хук pre-push на стороне клиента, чтобы поймать это, но это нужно будет настроить в каждом клоне, который будет отправлять в репозиторий. Это также не предотвратит слияние запрещенных коммитов с чем-то вроде автоматического слияния GitHub. - person qqx; 03.09.2014

Этот вопрос нужно решать как вопрос управления, а не вопрос автоматизации. Проблема в том, что TEST, скорее всего, также содержит большинство коммитов из двух других веток. Таким образом, вы не сможете эффективно идентифицировать коммиты, исходящие от TEST. Например, в нашей среде мы регулярно обновляем экспериментальные ветки новыми коммитами из основной ветки.

Вам нужен кто-то, кто будет выступать в роли менеджера по выпуску, чтобы гарантировать, что если что-то плохое будет объединено с мастером, то оно не будет развернуто до того, как проблема будет решена. Проблема не обязательно в плохом слиянии как таковом. Проблема заключается в развертывании плохого слияния.

Вы можете найти полезный инструмент на Bitbucket.org, где есть элементарный механизм утверждения коммитов. Это только совет, но может быть полезно для вас, чтобы отслеживать, какие коммиты были одобрены, а какие могли быть объединены по ошибке.

person platforms    schedule 14.11.2012
comment
да, было бы лучше управлять им, но у нас пока нет такого диспетчера выпусков (мы должны!), и мы используем основное репозиторий на основе сетевых ресурсов. мне было трудно убедить команду заменить TFS на GIT, и мне пришлось применить аналогичный рабочий процесс к TFS. Теперь, когда они все новички в GIT, я должен предотвратить их ошибочное нажатие, так как, как только кто-то нажимает, а кто-то тянет, прежде чем я это замечу, будет очень сложно что-то исправить. - person Volkan Ceylan; 15.11.2012