Как мы проверяем сообщения о фиксации для нажатия?

Происходя из CVS, у нас есть политика, что сообщения о фиксации должны быть отмечены с числом ошибки (простой суффикс "... [9999]"). Сценарий CVS проверяет это во время фиксаций и отклоняет фиксацию, если сообщение не соответствует.

Сообщение фиксации рычага мерзавца делает это на стороне разработчика, но мы находим полезным автоматизировать системную проверку и напомнить нам об этом.

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

Как мы проверяем сообщения о фиксации во время нажатия мерзавца?

25
задан Greg Bacon 26 March 2014 в 22:09
поделиться

3 ответа

Использование хуков обновления

Вы знаете о хуках - прочтите, пожалуйста, о них документация ! Хук, который вам, вероятно, нужен, - это update, который запускается один раз для каждой ссылки. (Ловушка предварительного приема запускается один раз за все нажатие) На SO уже есть множество вопросов и ответов об этих хуках; в зависимости от того, что вы хотите сделать, вы, вероятно, сможете найти руководство о том, как написать ловушку, если она вам понадобится.

Чтобы подчеркнуть, что это действительно возможно, цитата из документации:

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

Его также можно использовать для регистрации старого… нового статуса.

И особенности:

Ловушка выполняется один раз для каждой обновляемой ссылки и принимает три параметра:

  • имя обновляемой ссылки,
  • старое имя объекта, хранящееся в ссылке,
  • и новое имя объекта, которое будет сохранено в исх.

Так, например, если вы хотите убедиться, что ни одна из тем фиксации не превышает 80 символов, очень примитивной реализацией будет:

#!/bin/bash
long_subject=$(git log --pretty=%s $2..$3 | egrep -m 1 '.{81}')
if [ -n "$long_subject" ]; then
    echo "error: commit subject over 80 characters:"
    echo "    $long_subject"
    exit 1
fi

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

Зачем нужна ловушка обновления

Это обсуждалось / разъяснялось в комментариях; вот резюме.

Ловушка обновления запускается один раз для каждой ссылки.Ссылка - это указатель на объект; в данном случае мы говорим о ветвях и тегах и, как правило, просто о ветвях (люди не часто нажимают теги, поскольку они обычно используются только для маркировки версий).

Теперь, если пользователь отправляет обновления в две ветки, основную и экспериментальную:

o - o - o (origin/master) - o - X - o - o (master)
 \
  o - o (origin/experimental) - o - o (experimental)

Предположим, что X является «плохой» фиксацией, то есть той, которая не удала бы перехватчик commit-msg. Ясно, что мы не хотим соглашаться с тем, чтобы стать мастером. Итак, ловушка обновления отклоняет это. Но в экспериментальных коммитах нет ничего плохого! Ловушка обновления принимает это. Следовательно, origin / master остается неизменным, но origin / экспериментальный обновляется:

o - o - o (origin/master) - o - X - o - o (master)
 \
  o - o - o - o (origin/experimental, experimental)

Ловушка pre-receive запускается только один раз, непосредственно перед началом обновления ссылок (перед первым запуском ловушки update). Если бы вы использовали его, вам пришлось бы вызвать сбой всего push, таким образом говоря, что из-за плохого сообщения о фиксации на мастере вы почему-то больше не верите, что фиксации на экспериментальном уровне хороши, даже если их сообщения в порядке!

24
ответ дан 28 November 2019 в 21:30
поделиться

Вам необходимо создать сценарий для предварительного получения.

В этом скрипте вы получаете старую и новую ревизии. Вы можете проверить все фиксации и вернуть false, если что-то из этого плохое.

1
ответ дан 28 November 2019 в 21:30
поделиться

Вы можете сделать это с помощью следующих хук предварительного приема . Как отмечали другие ответы, это консервативный подход по принципу «все или ничего». Обратите внимание, что он защищает только главную ветку и не накладывает ограничений на сообщения фиксации в тематических ветках.

#! /usr/bin/perl

my $errors = 0;
while (<>) {
  chomp;
  next unless my($old,$new) =
    m[ ^ ([0-9a-f]+) \s+   # old SHA-1
         ([0-9a-f]+) \s+   # new SHA-1
         refs/heads/master # ref
       \s* $ ]x;

  chomp(my @commits = `git rev-list $old..$new`);
  if ($?) {
    warn "git rev-list $old..$new failed\n";
    ++$errors, next;
  }

  foreach my $sha1 (@commits) {
    my $msg = `git cat-file commit $sha1`;
    if ($?) {
      warn "git cat-file commit $sha1 failed";
      ++$errors, next;
    }

    $msg =~ s/\A.+? ^$ \s+//smx;
    unless ($msg =~ /\[\d+\]/) {
      warn "No bug number in $sha1:\n\n" . $msg . "\n";
      ++$errors, next;
    }
  }
}

exit $errors == 0 ? 0 : 1;

Это требует, чтобы все коммиты в push-сообщениях имели номер ошибки где-нибудь в их соответствующих сообщениях о фиксации, а не только в подсказке. Например:

$ git log --pretty=oneline origin/master..HEAD
354d783efd7b99ad8666db45d33e30930e4c8bb7 second [123]
aeb73d00456fc73f5e33129fb0dcb16718536489 no bug number

$ git push origin master
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 489 bytes, done.
Total 5 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
No bug number in aeb73d00456fc73f5e33129fb0dcb16718536489:

no bug number

To file:///tmp/bare.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'file:///tmp/bare.git'

Допустим, мы устраняем проблему, сжимая два коммита вместе и передавая результат:

$ git rebase -i origin/master
[...]

$ git log --pretty=oneline origin/master..HEAD
74980036dbac95c97f5c6bfd64a1faa4c01dd754 second [123]

$ git push origin master
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 279 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To file:///tmp/bare.git
   8388e88..7498003  master -> master
6
ответ дан 28 November 2019 в 21:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: