Git 'pre-receive' hook и скрипт 'git-clang-format' для надежного отклонения толчков, которые нарушают соглашения о стиле кода

Давайте сразу начнем с ломаpre-receive крючок, который я уже написал:

#!/bin/sh
##
  format_bold='\033[1m'
   format_red='\033[31m'
format_yellow='\033[33m'
format_normal='\033[0m'
##
  format_error="${format_bold}${format_red}%s${format_normal}"
format_warning="${format_bold}${format_yellow}%s${format_normal}"
##
stdout() {
  format="${1}"
  shift
  printf "${format}" "${@}"
}
##
stderr() {
  stdout "${@}" 1>&2
}
##
output() {
  format="${1}"
  shift
  stdout "${format}\n" "${@}"
}
##
error() {
  format="${1}"
  shift
  stderr "${format_error}: ${format}\n" 'error' "${@}"
}
##
warning() {
  format="${1}"
  shift
  stdout "${format_warning}: ${format}\n" 'warning' "${@}"
}
##
die() {
  error "${@}"
  exit 1
}
##
git() {
  command git --no-pager "${@}"
}
##
list() {
  git rev-list "${@}"
}
##
clang_format() {
  git clang-format --style='file' "${@}"
}
##
while read sha1_old sha1_new ref; do
  case "${ref}" in
  refs/heads/*)
    branch="$(expr "${ref}" : 'refs/heads/\(.*\)')"
    if [ "$(expr "${sha1_new}" : '0*

НОТА:
Места с нерелевантным кодом помечены# ....

НОТА:
Если вы не знакомы сgit-clang-format, взглянутьВот.

Этот хук работает, как и ожидалось, и до сих пор я не заметил никаких ошибок, но если вы заметите какие-либо проблемы или у вас есть предложения по улучшению, я буду признателен за любой отчет. Вероятно, я должен дать комментарий о том, что намерение стоит за этим крючком. Ну, он проверяет каждую отправленную ревизию на соответствие правилам стиля кода, используяgit-clang-formatи, если какой-либо из них не соответствует, он выведет соответствующий diff (тот, который сообщает разработчикам, что должно быть исправлено) для каждого из них. По сути, у меня есть два глубоких вопроса относительно этого крючка.

Во-первых, обратите внимание, что я выполняю копирование пустого (серверного) репозитория удаленного сервера в какой-то временный каталог и проверяю там код для анализа. Позвольте мне объяснить намерение этого. Обратите внимание, что я делаю несколькоgit checkoutс иgit resetс (из-заfor цикл), чтобы проанализировать все выдвинутые ревизии индивидуально сgit-clang-format, Здесь я пытаюсь избежать (возможной) проблемы параллелизма при принудительном доступе к пустому (серверному) репозиторию удаленного сервера. То есть у меня сложилось впечатление, что если несколько разработчиков попытаются одновременно протолкнуть на пульт с этимpre-receive хук установлен, что может вызвать проблемы, если каждый из этих push-сеансов не работаетgit checkoutс иgit resetс его частной копией хранилища. Итак, проще говоря, делаетgit-daemon есть встроенное управление блокировками для одновременных push-сессий? Будет ли он выполнять соответствующиеpre-receive перехватывать экземпляры строго последовательно или существует возможность чередования (что может привести к неопределенному поведению)? Что-то подсказывает мне, что для этой проблемы должно быть встроенное решение с конкретными гарантиями, иначе как в общем случае удаленные пульты (даже без сложных перехватчиков) будут подвергаться одновременным воздействиям? Если есть такое встроенное решение, то копия является избыточной, и простое повторное использование чистого хранилища фактически ускорит обработку. Кстати, любая ссылка на официальную документацию по этому вопросу очень приветствуется.

Во-вторых,git-clang-format только процессыпоставил (но не зафиксировано) изменения по сравнению с конкретным коммитом (HEAD по умолчанию). Таким образом, вы можете легко увидеть, где находится угловой корпус. Да, это скорень совершает (ревизии). По факту,git reset --soft 'HEAD~1' не может быть применено к корневым коммитам, так как у них нет родителей для сброса. Следовательно, есть следующая проверка с моим вторым вопросом:

        if [ "$(list --count "${sha1}")" -eq 1 ]; then
          # What should I put here?
        else
          git reset --soft 'HEAD~1' > '/dev/null' 2>&1
        fi

я пробовалgit update-ref -d 'HEAD' но это нарушает хранилище таким образом, чтоgit-clang-format больше не может его обрабатывать. Я полагаю, что это связано с тем, что все эти проверенные ревизии (включая эту корневую) еще не относятся к какой-либо ветви. То есть они вотдельный HEAD государство. Было бы идеально найти решение для этого углового случая, так чтоначальная коммиты также могут проходить такую ​​же проверкуgit-clang-format на соответствие правилам стиля кода.

Мир.

)" -ne 0 ]; then # delete unset sha1_new # ... else # update if [ "$(expr "${sha1_old}" : '0*

НОТА:
Места с нерелевантным кодом помечены# ....

НОТА:
Если вы не знакомы сgit-clang-format, взглянутьВот.

Этот хук работает, как и ожидалось, и до сих пор я не заметил никаких ошибок, но если вы заметите какие-либо проблемы или у вас есть предложения по улучшению, я буду признателен за любой отчет. Вероятно, я должен дать комментарий о том, что намерение стоит за этим крючком. Ну, он проверяет каждую отправленную ревизию на соответствие правилам стиля кода, используяgit-clang-formatи, если какой-либо из них не соответствует, он выведет соответствующий diff (тот, который сообщает разработчикам, что должно быть исправлено) для каждого из них. По сути, у меня есть два глубоких вопроса относительно этого крючка.

Во-первых, обратите внимание, что я выполняю копирование пустого (серверного) репозитория удаленного сервера в какой-то временный каталог и проверяю там код для анализа. Позвольте мне объяснить намерение этого. Обратите внимание, что я делаю несколькоgit checkoutс иgit resetс (из-заfor цикл), чтобы проанализировать все выдвинутые ревизии индивидуально сgit-clang-format, Здесь я пытаюсь избежать (возможной) проблемы параллелизма при принудительном доступе к пустому (серверному) репозиторию удаленного сервера. То есть у меня сложилось впечатление, что если несколько разработчиков попытаются одновременно протолкнуть на пульт с этимpre-receive хук установлен, что может вызвать проблемы, если каждый из этих push-сеансов не работаетgit checkoutс иgit resetс его частной копией хранилища. Итак, проще говоря, делаетgit-daemon есть встроенное управление блокировками для одновременных push-сессий? Будет ли он выполнять соответствующиеpre-receive перехватывать экземпляры строго последовательно или существует возможность чередования (что может привести к неопределенному поведению)? Что-то подсказывает мне, что для этой проблемы должно быть встроенное решение с конкретными гарантиями, иначе как в общем случае удаленные пульты (даже без сложных перехватчиков) будут подвергаться одновременным воздействиям? Если есть такое встроенное решение, то копия является избыточной, и простое повторное использование чистого хранилища фактически ускорит обработку. Кстати, любая ссылка на официальную документацию по этому вопросу очень приветствуется.

Во-вторых,git-clang-format только процессыпоставил (но не зафиксировано) изменения по сравнению с конкретным коммитом (HEAD по умолчанию). Таким образом, вы можете легко увидеть, где находится угловой корпус. Да, это скорень совершает (ревизии). По факту,git reset --soft 'HEAD~1' не может быть применено к корневым коммитам, так как у них нет родителей для сброса. Следовательно, есть следующая проверка с моим вторым вопросом:

        if [ "$(list --count "${sha1}")" -eq 1 ]; then
          # What should I put here?
        else
          git reset --soft 'HEAD~1' > '/dev/null' 2>&1
        fi

я пробовалgit update-ref -d 'HEAD' но это нарушает хранилище таким образом, чтоgit-clang-format больше не может его обрабатывать. Я полагаю, что это связано с тем, что все эти проверенные ревизии (включая эту корневую) еще не относятся к какой-либо ветви. То есть они вотдельный HEAD государство. Было бы идеально найти решение для этого углового случая, так чтоначальная коммиты также могут проходить такую ​​же проверкуgit-clang-format на соответствие правилам стиля кода.

Мир.

)" -ne 0 ]; then # create unset sha1_old sha1_range="${sha1_new}" else sha1_range="${sha1_old}..${sha1_new}" # ... fi fi # ... GIT_WORK_TREE="$(mktemp --tmpdir -d 'gitXXXXXX')" export GIT_WORK_TREE GIT_DIR="${GIT_WORK_TREE}/.git" export GIT_DIR mkdir -p "${GIT_DIR}" cp -a * "${GIT_DIR}/" ln -s "${PWD}/../.clang-format" "${GIT_WORK_TREE}/" error= for sha1 in $(list "${sha1_range}"); do git checkout --force "${sha1}" > '/dev/null' 2>&1 if [ "$(list --count "${sha1}")" -eq 1 ]; then # What should I put here? else git reset --soft 'HEAD~1' > '/dev/null' 2>&1 fi diff="$(clang_format --diff)" if [ "${diff%% *}" = 'diff' ]; then error=1 error '%s: %s\n%s' \ 'Code style issues detected' \ "${sha1}" \ "${diff}" \ 1>&2 fi done if [ -n "${error}" ]; then die '%s' 'Code style issues detected' fi fi ;; refs/tags/*) tag="$(expr "${ref}" : 'refs/tags/\(.*\)')" # ... ;; *) # ... ;; esac done exit 0

НОТА:
Места с нерелевантным кодом помечены# ....

НОТА:
Если вы не знакомы сgit-clang-format, взглянутьВот.

Этот хук работает, как и ожидалось, и до сих пор я не заметил никаких ошибок, но если вы заметите какие-либо проблемы или у вас есть предложения по улучшению, я буду признателен за любой отчет. Вероятно, я должен дать комментарий о том, что намерение стоит за этим крючком. Ну, он проверяет каждую отправленную ревизию на соответствие правилам стиля кода, используяgit-clang-formatи, если какой-либо из них не соответствует, он выведет соответствующий diff (тот, который сообщает разработчикам, что должно быть исправлено) для каждого из них. По сути, у меня есть два глубоких вопроса относительно этого крючка.

Во-первых, обратите внимание, что я выполняю копирование пустого (серверного) репозитория удаленного сервера в какой-то временный каталог и проверяю там код для анализа. Позвольте мне объяснить намерение этого. Обратите внимание, что я делаю несколькоgit checkoutс иgit resetс (из-заfor цикл), чтобы проанализировать все выдвинутые ревизии индивидуально сgit-clang-format, Здесь я пытаюсь избежать (возможной) проблемы параллелизма при принудительном доступе к пустому (серверному) репозиторию удаленного сервера. То есть у меня сложилось впечатление, что если несколько разработчиков попытаются одновременно протолкнуть на пульт с этимpre-receive хук установлен, что может вызвать проблемы, если каждый из этих push-сеансов не работаетgit checkoutс иgit resetс его частной копией хранилища. Итак, проще говоря, делаетgit-daemon есть встроенное управление блокировками для одновременных push-сессий? Будет ли он выполнять соответствующиеpre-receive перехватывать экземпляры строго последовательно или существует возможность чередования (что может привести к неопределенному поведению)? Что-то подсказывает мне, что для этой проблемы должно быть встроенное решение с конкретными гарантиями, иначе как в общем случае удаленные пульты (даже без сложных перехватчиков) будут подвергаться одновременным воздействиям? Если есть такое встроенное решение, то копия является избыточной, и простое повторное использование чистого хранилища фактически ускорит обработку. Кстати, любая ссылка на официальную документацию по этому вопросу очень приветствуется.

Во-вторых,git-clang-format только процессыпоставил (но не зафиксировано) изменения по сравнению с конкретным коммитом (HEAD по умолчанию). Таким образом, вы можете легко увидеть, где находится угловой корпус. Да, это скорень совершает (ревизии). По факту,git reset --soft 'HEAD~1' не может быть применено к корневым коммитам, так как у них нет родителей для сброса. Следовательно, есть следующая проверка с моим вторым вопросом:

        if [ "$(list --count "${sha1}")" -eq 1 ]; then
          # What should I put here?
        else
          git reset --soft 'HEAD~1' > '/dev/null' 2>&1
        fi

я пробовалgit update-ref -d 'HEAD' но это нарушает хранилище таким образом, чтоgit-clang-format больше не может его обрабатывать. Я полагаю, что это связано с тем, что все эти проверенные ревизии (включая эту корневую) еще не относятся к какой-либо ветви. То есть они вотдельный HEAD государство. Было бы идеально найти решение для этого углового случая, так чтоначальная коммиты также могут проходить такую ​​же проверкуgit-clang-format на соответствие правилам стиля кода.

Мир.

Ответы на вопрос(1)

Ваш ответ на вопрос