Стратегия предотвращения или отлова переписывания git-истории - PullRequest
38 голосов
/ 18 января 2010

Хотя мне нравится функция перезаписи истории git, как можно сделать так, чтобы история не переписывалась.

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

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

Ответы [ 3 ]

40 голосов
/ 18 января 2010

Если вы можете запустить:

 git config --system receive.denyNonFastforwards true

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

git config:

receive.denyNonFastForwards

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

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


Как ebneter (кто знает о важности связного репозитория - см. Ответ о SVN для миграции на Git [вопрос теперь удален, 10K + только для пользователей ]) комментарии:

Возможно, вы также захотите добавить receive.denyDeletes true, потому что в противном случае кто-то может просто удалить ветку, а затем вставить свою переписанную ветвь как новую ветвь, эффективно переписывая историю.

git config

Один из обходных путей для политики denyNonFastForwards состоит в том, чтобы пользователь удалил ветвь и затем снова поднял ее с новой ссылкой. В более новых версиях Git (начиная с версии 1.6.1) вы можете установить для receive.denyDeletes значение true:

$ git config --system receive.denyDeletes true

Это запрещает удаление веток и тэгов по всей доске - ни один пользователь не может это сделать. Чтобы удалить удаленные ветки, вы должны удалить файлы ref с сервера вручную. Есть также более интересные способы сделать это для каждого пользователя через ACL, о чем вы узнаете в конце этой главы.

3 голосов
/ 19 января 2010

Если вы не используете достаточно новый git для receive.denyNonFastForwards, вы можете применить политику через {pre,post}-receive (среди прочего) перехватчиков на сервере, что позволяет немного увеличить степень детализации для определенных веток и т.

Несколько хороших примеров (в том числе одно запрещающее переписывание истории) используются проектом GNOME для управления всеми там репозиториями:

https://git.gnome.org/browse/sysadmin-bin/tree/git

В частности, я бы посмотрел pre-receive-check-policy .

0 голосов
/ 07 января 2013

Если вы не можете / не хотите полностью отключить переписывание истории Git, но хотите получать уведомления о каждом изменении такого рода и иметь возможность восстановления даже спустя годы, существуют расширения для корпоративных серверов Git, такие как Gerrit, которые будут обнаруживать перезапись истории и удаления ветвей, создаст их резервные копии под специальной ссылкой, так что они могут быть восстановлены при необходимости и не будут удалены сборщиком мусора. Администраторы Gerrit могут по-прежнему удалять выбранные коммиты, если это необходимо по юридическим причинам.

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