2012-09-30 2 views
1

Я использовал git filter-branch, чтобы обновить большое количество коммитов в одном из моих хранилищ (исправление автора и сообщение коммиттера было неправильным). Команда, которую я использовал, была:Есть несколько историй в хранилище git, которые могут вызывать будущие проблемы?

git filter-branch -f --env-filter "GIT_AUTHOR_EMAIL='[email protected]'; GIT_COMMITTER_EMAIL='[email protected]';" 

Вслед за мерзавцем притяжением для синхронизации с удаленным хранилищем

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

Является ли это проблемой? Или я могу спокойно оставить обе истории там?

+1

Я вижу, что вы добавили команду 'filter-branch', но это само по себе не вызвало бы график, который я вижу. Возможно, дополнительная команда связана с нажатием на ваш репозиторий? Я подозреваю, что вы следовали часто используемой (и очень неправильной) практике ввода «git pull» всякий раз, когда «push» отвечает «ошибкой [отклонен] ... non-fastforward». Это так? –

+0

@Will - вы вполне можете быть правы, я думаю, что я, возможно, по ошибке ошибся ... что бы объединило две истории вместе? Я так понимаю, я должен заставить толчок здесь вместо этого? – mikera

+0

правильно, я обновлю свой ответ, чтобы объяснить более подробно –

ответ

5

Во-первых, git filter-branch предназначен для перезаписи истории, а не для создания параллельной истории рядом с другой. Если вы закончили операцию filter-branch путем слияния, вы использовали ее неправильно.

Это может привести к путанице, поскольку иногда вы можете увидеть одну, а иногда и другую линию истории. Каждый раз, когда у вас есть несколько строк истории, делающих одинаковые изменения, это плохо. Представьте себе операции, такие как bisect или blame, где вы пытаетесь найти фиксацию, которая ввела конкретное изменение. Теперь часто бывают две исторические фиксации, которые на самом деле делают то же самое - чего вы хотите?

Даже основные операции, такие как git log, при наличии даты, могут показывать длинные прогоны «дубликатов». Очевидно, что это нежелательное поведение.

Более идеологическое примечание. Должны ли вы даже переписывать историю, чтобы исправить такую ​​незначительную проблему? git имеет функцию для этой точной ситуации: «mailmap».

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

Обратите внимание, что при выполнении команд перезаписи истории, таких как filter-branch или rebase, опубликованная история сделает это так, что git больше не будет считать ваши локальные коммиты «основаны на» существующим восходящим коммитом.В связи с этим, выдвигая обычно приводит к ошибке, например:

! [rejected]  master -> master (non-fast forward) 

Таким образом, вы должны «силы» толчок, то есть: git push -f. Стандартные оговорки в отношении -f применяются (обязательно, чтобы не захлопнуть чьи-либо коммиты), и, конечно же, предупреждения о rewriting public history.

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

  • Любой с существующей копии, которые не перебазироваться к вашей новой истории до нажатия, получит предупреждение «не быстрая перемотка вперед», и могут предположить, что они должны слиться.
  • Любой, кто объединяет старую историю с новой и толкает, приведет к восстановлению «старой» истории.
  • Старые ссылки в списках рассылки, электронные письма и т. Д. Для фиксации идентификаторов из «старой» истории больше не будут иметь значения.

Из-за третьего пункта я рекомендую хранить ярлык «старой» истории, так что любые исторические обсуждения, в которых упоминаются идентификаторы фиксации, все равно будут отображаться где-то действительными. Назовите тег чем-то, что делает очевидным, что тег не, который будет использоваться для новой разработки.

+0

большое спасибо - заработал он через ваш хороший совет! – mikera

2

Ну, для начала вы по-прежнему будете совершать неправомерные сообщения в своей истории, так что вы действительно ничего выиграли? :-)

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

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

+0

Делает смысл .... но тогда как лучше всего исправить это? Был ли 'git filter-branch' неправильным инструментом для этой работы? Или я должен использовать какой-либо другой инструмент для удаления старой истории? – mikera

+0

'git filter-branch' - правильный инструмент. Сначала используйте 'git reset --hard COMMITNAME' для принудительной перемотки вашей локальной истории до слияния. Затем просто нажмите эту фиксацию на сервер = используйте 'git push -force', чтобы перезаписать историю сервера. –

+0

все, кажется, работает сейчас - спасибо Петру! – mikera