Редактировать сообщения других разработчиков GIT на TFS
Меня спросили, могу ли я изменить набор отмеченных в комментариях в истории git для проекта, который содержит несоответствующую формулировку другого разработчика.
Может кто-нибудь показать мне, как этого добиться (или подтвердить, если это невозможно)? Я администратор TFS, поэтому права доступа не являются проблемой. Наша TFS использует SQL Express & GIT в качестве источника контроля. Версия TFS: 15.117.26714.0
Мы используем Visual Studio 2017 на наших локальных компьютерах с плагином Team Explorer.
2 ответа
Это может быть сделано, но это, скорее всего, будет хлопот. В зависимости от характера правила аудита вы можете подумать, предлагают ли git notes лучшее решение. (Если вам просто не хватает информации, и если ваши аудиторы согласятся с ней, добавление заметок позволит вам добавить дополнительную информацию с минимальным нарушением. Если вам нужно удалить информацию - если кто-то вводил пароли, или организационно-неприемлемый язык или что угодно в сообщениях - тогда это не поможет.)
Вы можете заметить, что некоторые другие системы контроля версий позволяют более свободно редактировать сообщения коммитов. Я не хотел бы принимать решение об управлении исходным кодом для моей команды на этой основе, но это вопрос, если это частое требование для вашей команды. Или еще лучше выяснить, нужно ли что-то корректировать, чтобы это не было частым требованием в будущем.
(В некоторой степени это может быть проблемой обучения тому, что требуется и / или запрещено в сообщениях о фиксации. Возможно, вы сможете настроить некоторый вид защитного ограждения с помощью перехватчиков - перехват предварительного приема является наиболее важным, если ваша среда хостинга позволит вам настроить один из них, и предварительная фиксация ловушек будет хорошим удобством для разработчиков, чтобы убедиться, что любые ошибки "быстро проваливаются".)
Проблема в том, что сообщение коммита является неотъемлемой частью коммита. Когда вы изменяете сообщение коммита (давайте назовем его P
), вы действительно создаете новый коммит (P'
). Кроме того, если у вас есть коммит C
и вы хотите изменить его родителя с P
в P'
, тогда вы должны заменить его новым коммитом C'
,
Разница между изменением коммитов и заменой их новыми коммитами не так уж и много, но на практике это означает, что вы удаляете исходные коммиты из истории опубликованных веток, и именно здесь это становится проблемой.
Чтобы сделать очистку, начните с любого клона. Предположим, у нас есть следующее, где коммиты без имени 'x' имеют плохие коммиты.
x -- x -- x -- A <--(master)(origin/master)
\
x -- x - x -- B -- x <--(branch1)(origin/branch1)
\ /
x -- C -- x <--(branch2)(origin/branch2)
фиксация A
не слишком сложно
git checkout master
git commit --amend
представит редактор, и вы можете переписать сообщение коммита. (Или вы можете включить git commit
варианты, такие как -m
указать сообщение фиксации.) Тогда у вас есть
A' <--(master)
/
x -- x -- x -- A <--(origin/master)
\
x -- x - x -- B -- x <--(branch1)(origin/branch1)
\ /
x -- C -- x <--(branch2)(origin/branch2)
Обратите внимание, что A
все еще существует и origin/master
все еще указывает на это. Это важно. Это означает, что когда вы хотите обновить origin
тебе придется сказать
git push -f
и это "сломает" чужой клон. Увидеть git rebase
docs ( https://git-scm.com/docs/git-rebase) в разделе "Восстановление из исходной версии" для получения дополнительной информации о проблеме и типичной процедуре очистки; но также обратите внимание на то, что, если оказывается, что это переписывает большую часть репо, вы можете вместо этого следовать процедуре вырезания, подобной этой:
- Каждый толкает весь свой код; это не должно быть полностью объединено, но должно быть в
origin
, так как - Каждый отбрасывает своих клонов
- Вы делаете свою работу по уборке
- Каждый делает новый клон
В любом случае, у вас есть один очищенный коммит. На B
, На этот раз это не ветка, так что amend
это не то, что нужно использовать. Вместо этого сделайте rebase
,
git rebase -i branch1~2 branch1
Вы получите список "задач", который показывает каждую из последних двух коммитов на branch1
, Найти запись для B
и изменить начало строки с pick
в reword
, Затем пусть перебазирование продолжается, и когда оно достигает B
это даст вам редактор для сообщения коммита. В конце концов у вас есть
A' <--(master)
/
x -- x -- x -- A <--(origin/master)
\
x --- x --- x -- B -- x <--(origin/branch1)
\ / \
\ / B' -- x' <--(branch1)
\ /
x - C -- x <--(branch2)(origin/branch2)
Не намного хуже чем A
; ты переписал x
совершать из-за переучивания, но, в конце концов, это всего лишь еще одна ссылка на форс-пуш.
Теперь насчет C
? Что ж, C
достижимо из нескольких ссылок, и для одного из этих коммитов есть слияние между ними. Эти факторы делают rebase
гораздо сложнее правильно использовать. В этом случае вы можете использовать git filter-branch
, (Если у вас есть какие-либо случаи, которые заставляют вас использовать filter-branch
, тогда вы могли бы рассмотреть возможность сделать один filter-branch
сделать все ваши переписывания, а не возиться с отдельным rebase
или же amend
операции.)
Проблема в том, как написать msg-filter
, Вы можете написать скрипт, который проверяет идентификатор коммита, для каждого известного "плохого" коммита выводится соответствующее новое сообщение коммита, а для всего остального просто cat
Вернуть оригинальное сообщение. Или вы можете просто запустить редактор для каждого коммита, если коммитов не так много для практического применения. Или что-то среднее (запускать редактор для каждого коммита, чей идентификатор находится в определенном списке). Существует слишком много подходов и слишком много причин, которые могут повлиять на то, какой подход использовать, чтобы подробно описать этот ответ.
Предполагая, что вы разберетесь со скриптом фильтра, вы сделаете что-то вроде
git filter-branch --msg-filter=my-filter-script -- --all
Полная диаграмма для этого результата становится грязной, но в основном для местных филиалов C
заменяется на C'
все, что может достичь C
аналогичным образом заменяется, и каждая ветвь из которой C
достижимо, нужно толкать силой.
Из командной строки вы можете использовать
git rebase -i <sha-hash of the first commit to edit>~
(Обратите внимание на тильду в конце. Вы должны ввести это буквально.)
После ввода этого текста откроется текстовый редактор со списком всех коммитов и командой, что с ними делать. По умолчанию команда pick
, Для тех, кого вы хотите редактировать, выберите reword
, Затем сохраните файл и закройте текстовый редактор. Теперь для каждого коммита, который вы решили перефразировать, редактор снова откроется и позволит вам редактировать сообщение коммита. После редактирования просто сохраните и закройте.
Обратите внимание, что это перезапишет всю историю git с того момента, с которого вы начали. Любой, кто ранее извлек эту историю в локальный репозиторий, должен git fetch
а потом git reset --hard <branch name>
, Если они этого не сделают, то оскорбительные коммиты останутся в репо, так как они продолжают работать.