Если я попытаюсь удалить ветку из GIT-репозитория Azure DevOps, потребуется разрешение Force Push в соответствии с показанным сообщением об ошибке:
Однако разрешение «принудительных толчков» также позволяет переписать историю. Это даже прямо указано в месте настройки этих прав.
В моем понимании Git ветки — это не что иное, как закладки/ярлыки для изменений. В некотором смысле, это особый вид тегов. Если они отбрасываются во время слияния, принудительное нажатие вправо не требуется.
Я хотел бы разрешить людям удалять ветки, не давая им права возиться с историей. Они не должны иметь возможности редактировать/удалять фактический набор изменений, но они могут делать все, что захотят, с этими особыми типами тегов. Как мне это настроить?
Или я неправильно понимаю, сколько истории можно переписать, допуская силовые толчки? Все, что я хотел бы сохранить, это то, какое изменение кода было проверено кем. Можно ли сломать эту историю, разрешив силовые толчки?
Итак, я сделал несколько коммитов в ветке за веткой, и какой-то другой парень решил выбросить мою ветку и сделать новые коммиты? В этом случае все коммиты были сделаны другим парнем. В редких случаях, когда это происходит, я все еще могу найти свои (осиротевшие) коммиты в репозитории. Но опять же - «переписать историю» предполагает, что другой парень может изменить или изменить мои коммиты. Это может быть недоразумение с моей стороны.
git commit -m "Haha I'll destroy this app" --author = "realbart"
(я хочу сказать, что git не имеет функций аутентификации как таковых, люди могут делать коммиты, «авторские» вами, и продвигать их.)
@RomainValeri хороший момент: вы действительно можете подделывать учетные данные / подделывать других пользователей без принудительного нажатия, если только вы не используете подписанные коммиты, но, насколько я знаю, нет никакого способа предотвратить это. Итак, какой рекомендуемый способ справиться с этим? Просто сохранить каждую ветку, которая когда-либо была нажата навсегда?
Я хотел бы разрешить людям удалять ветки, не давая им права возиться с историей.
Основываясь на доступных параметрах разрешений, вы не можете добиться именно того, о чем просите, однако оказывается, что в любом случае, вероятно, есть лучший способ. Если применимо tl; dr, перейдите к нижнему разделу: «Где вы, вероятно, хотите приземлиться».
Вопрос: Что такое «форс-толчок»?
Мы обычно говорим: «силовой толчок переписывает историю». Другой способ подумать об этом, который может быть более полезным в контексте этого вопроса: «Принудительное нажатие» требуется каждый раз, когда вы хотите удалить одну или несколько коммитов из доступной истории ветки. Если вы этого не делаете, и кончик удаленной ветки доступен для нового коммита наконечника, который вы отправляете, то будет достаточно обычного нажатия.
Вопрос: Почему «принудительное нажатие» и «удаление веток» объединены в одно и то же разрешение?
Рассмотрим ветку, которая достигает 3 коммитов: A-B-C
Добавьте один коммит: A-B-C-D
= обычный push.
Удалить один коммит: A-B
= принудительное нажатие.
Полностью заменить один коммит (т.е. удалить один и добавить один коммит): A-B-X
= принудительно нажать.
Слегка измените один коммит (т.е. удалите один и добавьте один коммит): A-B-C'
= принудительное нажатие.
Удалить все коммиты (т.е. удалить ветку) = принудительно нажать.
Если мы определим «принудительное нажатие» как «удаление одного или нескольких коммитов из ветки», то удаление ветки концептуально является подмножеством этого (удаление всех коммитов), и существует специальный синтаксис для удаления ветки: git push -d origin my-branch
или git push origin :my-branch
.
Теперь давайте предположим, что мы сделали то, что вы просили: мы могли бы определить «принудительное нажатие» как «удалить один или несколько коммитов, но не все коммиты», а затем разделить разрешения, чтобы вы разрешили «удалить ветку», но не разрешили «принудительно толкать". Как указано в комментарии Ромена Валери, нет ничего, что помешало бы кому-то удалить ветку, а затем повторно использовать это имя ветки для отправки нового коммита, в любом случае эффективно достигая «форсированного толчка». При этом, если вы добавите третье разрешение для «Создать новую ветку», то, возможно, ваше желание сработает. Однако разрешение людям удалять ветку, но не создавать ветку, скорее всего, вызовет больше проблем, чем решит в большинстве рабочих процессов. (Это не значит, что никто не найдет в этом ценности...)
Вопрос: Когда можно использовать принудительное нажатие?
Это сильно зависит от вашей ситуации и предпочтений. Некоторые люди считают, что ответ «никогда», хотя эта строгая догма, вероятно, принадлежит меньшинству. Позиция большинства состоит в том, чтобы запретить принудительное нажатие общих ветвей и разрешить принудительное нажатие в противном случае. В целом, и особенно в частных репозиториях, люди довольно часто имеют свои личные ветки, над которыми они работают, и поэтому рекомендуется регулярное перемещение этих веток на общую цель, поэтому принудительное нажатие личных веток будет считаться нормальным и частое возникновение. Поэтому в частном репозитории AzDO имеет смысл разрешить как удаление, так и принудительную отправку ветки, если это личная ветка.
Для всех пользователей, которые будут вносить свой вклад в любые репозитории AzDO Git, по умолчанию установлено:
Разрешить «Вклад» и «Принудительное нажатие».
Не устанавливается для всего остального.
Обратите внимание, что эти настройки будут применяться к большинству ветвей.
Для определенных защищенных ветвей используйте политики ветвей. Это потребует запроса на слияние (со многими настраиваемыми параметрами) для слияния с защищенными ветками, а также эффективно предотвращает принудительное нажатие или удаление этих веток.
Для защищенных ветвей при необходимости можно добавить дополнительную защиту, отключив наследование, а затем при необходимости установив явную защиту. В этом случае вы можете добавить «Contribute» для набора пользователей, которые могут выполнять PR в ветке, но (вероятно) не включать «Force Push» на этот раз1. Примеры дополнительных разрешений могут включать:
Я думаю, важно отметить, что за кулисами AzDO фактически придает значение создателю ветки. Эта концепция на самом деле не существует в Git, но (методом проб и ошибок я это подтвердил) AzDO определяет ее как:
Создатель ветки — это последний аутентифицированный пользователь, отправивший имя ветки, когда ее не существовало.
Обратите внимание, что это означает, что создатель ветки может измениться, например, если ветка удалена, а затем кто-то другой отправляет ветку с тем же именем - последний человек, который отправляет ее, пока она не существует, становится создателем. Кроме того, отправителем является лицо, прошедшее аутентификацию в AzDO (либо в клиенте, либо в пользовательском интерфейсе); этот человек не имеет ничего общего с автором коммитов на ветке.
Интересная часть здесь заключается в том, что «создатель» ветки автоматически получает дополнительные разрешения для этой ветки, включая разрешения принудительной отправки, что означает, что если вы не включите принудительную отправку для всех по умолчанию, как я рекомендовал выше, этот человек (или администратор или группа людей, которым специально предоставлены разрешения на принудительную отправку) по-прежнему могут удалить свою собственную ветку. ИМХО, это была действительно хорошая попытка избежать предоставления всем принудительных разрешений, но на практике я обнаружил, что это не работает. Проблема в том, что когда вы выбираете опцию удаления вашей ветки после завершения PR, это будет работать только в том случае, если «создателем» этой ветки является человек, который завершил PR. Если кто-то еще завершит PR, удаление ветки не удастся. Это достаточно серьезная проблема в моем рабочем процессе, поскольку многие люди завершают PR других людей, поэтому мы должны по умолчанию давать всем разрешение на принудительную отправку.
1 Обратите внимание, что после включения политик ветвей для принудительной отправки у вас должно быть установлено «Разрешить» для двух разрешений: «Принудительная отправка» и «Обход политик при отправке». Это означает, что любой пользователь может иметь один или другой, если у него нет обоих. Вот почему вы «вероятно» хотите удалить разрешение «принудительно нажать» для всех в защищенных ветвях в целях безопасности, но на самом деле это может быть необязательно.
Вопрос: Потерянные коммиты не удаляются из репозитория, не так ли? Если я все еще знаю идентификатор, я все равно могу их проверить, верно? И с правильными инструментами я мог их визуализировать?
Правильно. AzDO не удаляет потерянные коммиты. Вы по-прежнему можете найти идентификаторы коммитов в журналах push-уведомлений или в PR, если он существовал в то время. Как только вы узнаете идентификатор, вы можете перейти к нему напрямую (нажмите на любую ссылку фиксации, а затем измените идентификатор фиксации в URL-адресе), а оттуда вы можете создать новую ветку в этой фиксации, если хотите. Вы также можете получить любой известный идентификатор с помощью git fetch origin <full-40-char-hash>
, и как только он будет у вас локально, вы сможете делать с ним все, что захотите.
Так что на мой взгляд, термин "переписать историю" выбран неудачно. Это вызвало панику в нашем ИТ-отделе и заблокировало это право для всех. Для меня изменения — это история. Ветки и теги — это просто закладки.
@realbart Если вы считаете, что «ветвь» — это, по сути, указатель на один коммит, то, когда вы добавляете новые коммиты, вы «добавляете историю» в эту ветку, но если вы удаляете коммит, вы действительно «переписываете историю» этого ветвь. Я думаю, что паника возникла из-за непонимания того, что «переписывание истории» короткоживущих веток функций, которые вы все равно удалите, не имеет никакого значения, но «переписывания истории» долгоживущих общих веток определенно следует избегать!
@realbart на самом деле этого не было в моем ответе, но ваша точка зрения о тегах также верна. Если вы пометите конкретные сборки, которые вас интересуют, даже если они больше не доступны для переписанной или удаленной ветки, каждый все равно может легко увидеть их для дальнейшего использования. Эти идентификаторы коммитов сохраняются впереди и по центру тегами.
Что помешает им удалить ветку и отправить новую версию (таким образом... полностью переписав ее историю, если они того пожелают)?