Git pre-push hook, чтобы отклонить добавление строки в общие изменения - PullRequest
0 голосов
/ 01 февраля 2019

Как бы вы написали ловушку предварительного толчка, которая отклоняет толчок, когда общий diff вводит определенное слово / предложение / строку?

Мотивирующий вариант использования:

  1. фиксация TODO заметок (пометка задач для завершения перед нажатием)
  2. , позволяющая git не забыть обратиться к упомянутым заметкам при нажатии

Примечания:

  1. Я видел много разных вопросов и ответов, но ни один из них не приблизился.Те, которые пытаются быстро потерпеть неудачу в крайних случаях (например, это и это ).
  2. замечают, что "общий diff" означает, что фиксация добавления TODO будет разрешено до тех пор, пока строка была удалена при последующих нажатиях (так, чтобы общая дельта не содержала его)
  3. основная трудность - найти диапазон для передачина git diff, который работает во всех случаях.
  4. должны быть заблокированы только добавления TODO, удаление должно быть разрешено в модификациях diff
  5. строк, ранее содержащих TODO, которые поддерживаютэто подразумевает добавление TODO (даже если одновременно с удалением) и поэтому должно быть заблокировано (обоснование: нет объективного способа определить, является ли введенный TODO тем же , что и удаленный).
  6. такой хук должен справляться со всеми действительными толчками , проверяя только дельты, соответствующие диапазонам новых коммитов (например, ничего проверять в push --delete).Некоторые конкретные случаи для рассмотрения:
    • новые ветви
    • удаленные ветви
    • переименованные ветви
    • ветвление чего-то другого, кроме master (поэтому нет merge-base origin/master)
    • разбивает / объединяет
    • теги
    • принудительные толчки
  7. Изменение бонуса: предотвращение нажатия любые коммиты, добавляющие TODO (а не в общий diff).

1 Ответ

0 голосов
/ 05 февраля 2019

Можно попробовать что-то вроде следующего.

#!/usr/bin/env ruby

branchName = `git rev-parse --abbrev-ref HEAD`.strip
log = `git reflog show --no-abbrev #{branchName} --format='\%h'`.split("\n")
range = "#{log.last}..#{log.first}".gsub("'", "")

`git diff --name-only --diff-filter=ACMR #{range}`.each_line do |file|
  file = file.chomp
  command = "git show #{log.first}:#{file}".gsub("'", "")
  content = `#{command}`

  if ( content =~ /TODO/ )
    puts "'#{file}' contains TODO"
    exit 1
  end
end

exit 0

Это будет искать в содержимом любых новых, добавленных, измененных или переименованных файлов слово TODO.Если он найдет слово, он выйдет и выведет имя файла, содержащего соответствующее регулярное выражение.

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

...