Может ли git rebase полностью удалить удаленную историю?

Поскольку мы рассматриваем возможность перехода от SVN к git, сотрудник обеспокоен тем, что вредоносный или подверженный риску разработчик мог использовать git rebase для удаления удаленной истории из нашего общего репо.

Изменить: Как указано в ответах, целые ветки также можно удалить из удаленного репо с помощью git push origin :branch-name.

Является ли это реальной проблемой? Если да, то какой подход мы можем предпринять, чтобы предотвратить его?

Ответ 1

Я склонен соглашаться с вашим коллегой, что здесь проблема, потому что:

  • Независимо от того, насколько хорошо вы доверяете своим коммиттерам, всегда есть возможность человеческой ошибки.
  • более обременительные процессы обзора (например, Gerrit) не всегда подходят
  • восстановление из резервных копий может быть медленным, а PITA

Вы рассмотрели receive.denyNonFastForwards и receive.denyDeletes параметры конфигурации? AFAICT доступны в Git 1,6 и далее.

Из Pro Git:

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

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

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

Как упоминает автор, это правило также может быть выполнено с помощью крючка приема (который описан позже в Pro Git).

Эти методы должны защищать от случайной (или вредоносной) утраченной истории в вашем общем репо.

Ответ 2

История может быть испорчена с помощью rebase, но обычно удаленное репо не принимает изменения, которые изменяют историю (если вы не используете git push -force), но даже больше, разработчик с разрешением push может удалить полностью (git push origin: branch-name). Итак, простые правила:

  • Не позволяйте push-разрешения разработчикам, которым вы не доверяете.

  • Когда репо используется совместно, не связывайтесь с историей, избегайте использования rebase на прошлых фиксациях. Вместо этого используйте merge или cherry-pick, если вам нужно добавить что-то из другой ветки, и в этом случае история не будет затронута.

  • Вы можете поддерживать политику не использовать 'push -f' для общего репо, и в этом случае разработчик будет знать, что если push отпадает, то что-то идет не так (скорее всего, локальная ветка не обновляется с удаленный) и должен решить проблему локально, а не форсировать push.

Что касается вашего вопроса о том, как предотвратить - используйте систему проверки Gerrit, это похоже на промежуточный шаг на пути фиксации между разработчиком локальный репозиторий и мастер-репо с хорошим веб-интерфейсом для пересмотра, вы можете дать разрешения на то, чтобы перенаправить репозитарий в репозиторий, но изменение будет объединено в ваш основной ветвь после проверки и утверждения (для чего требуются некоторые разрешения, которые вы обычно предоставляете основным разработчикам), Вы можете увидеть, как это выглядит в проекте Mahara: https://reviews.mahara.org В этом конкретном случае только богу gerrit можно нажать на мастер (который здесь) и никто другой.

Ответ 3

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