Подтвердить что ты не робот

TFS: Слияние обратно в главную ветку

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

Теперь я хочу слить обратно в Current. Сначала я объединил Current to Experimental, скомпилировал и убедился, что все работает. Поэтому в моей голове эксперимент и ток должны быть "синхронными". Но когда я пытаюсь объединить Experimental обратно в Current, я получаю целую кучу конфликтов. Но я думал, что уже решил, когда я объединил "Ток в Экспериментальный".

Что происходит? Я что-то совершенно не понял? Как я могу сделать это плавно? На самом деле не хотят проходить через все эти конфликты...

4b9b3361

Ответ 1

Когда вы нажимаете "Разрешить" в отдельном конфликте, что говорится в сводном сообщении? Если ваши слияния с Current → Experimental были завершены без основной ручной работы, это должно быть что-то вроде "X source, 0 target, Y both, 0 conflicting". Другими словами, в целевом (текущем) файле нет блоков контента, которые еще не находятся в копии источника (Experimental). Вы можете безопасно использовать кнопку AutoMerge All.

Примечание. AutoMerge должен быть безопасным независимо. Он оптимизирован, чтобы быть консервативным относительно ранних предупреждений, а не для способности решать каждый случай. Но я признаю, что многие из нас - включая меня - любят запускать инструмент слияния, когда есть вопрос. В описанном сценарии ИМО, даже самый пугливый, может успокоиться.


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

  • настройте две ветки, A и B.
  • внести изменения в A\foo.cs и B\foo.cs в отдельных частях файла
  • merge A → B
  • Автоответчик конфликта
  • merge B → A

TFS должен отмечать эту последовательность событий как конфликтующую. Ближайший общий предк между B\foo.cs; 4 и A\foo.cs; 2 лежит на первом шаге, и с тех пор обе стороны явно изменились.

Загадочно сказать, что A и B синхронизируются после шага 4. (Точнее: общий предк для слияния шага 5 - версия № 2). Несомненно, успешное слияние контента подразумевает, что B\foo.cs содержит все изменения, внесенные на сегодняшний день? К сожалению, есть ряд причин, по которым вы не можете этого сделать:

  • Общность: не все конфликты могут быть автоматическими. Вам нужны критерии, которые применяются к обоим сценариям.

  • Правильность: даже когда AutoMerge преуспевает, он не всегда генерирует действительный код. Классический пример возникает, когда два человека добавляют одно и то же поле в разные части определения класса.

  • Гибкость: каждый пользователь, контролирующий исходный код, имеет свои собственные любимые инструменты слияния. И они нуждаются в способности продолжать разработку/тестирование между первоначальным решением Resolve [ "нужно как-то объединить содержимое когда-нибудь" ] и окончательной Checkin [ "здесь, это работает" ].

  • Архитектура: в такой централизованной системе, как TFS, сервер просто не может доверять чему-либо, кроме своей собственной базы данных + требованиям проверки API. Пока вход соответствует спецификации, сервер не должен пытаться отличить, как выполнялись различные типы сличений контента. (Если вы считаете, что сценарии до сих пор легко различаются, подумайте: что, если у механизма AutoMerge есть ошибка? Что делать, если клиент-изгоев вызывает веб-сервис напрямую с произвольным содержимым файла? Только царапины на поверхности здесь... серверы должны быть скептически по какой-то причине!) Все, что можно смело рассчитать, вы отправили мне результирующий файл, который не соответствует источнику или цели.

Объединяя эти требования вместе, вы получаете дизайн, который объединяет наши действия на шаге 4 в довольно широкую категорию, которая также включает ручные слияния, возникающие из-за перекрывающихся изменений, объединение контента [автоматически или нет], предоставляемое сторонними инструментами, и файлы, отредактированные вручную после факта. В терминологии TFS это разрешение AcceptMerge. Как только они зарегистрированы как таковые, Правила слияния (tm) должны взять на себя худшее в стремлении к исторической целостности и безопасности будущих операций. В процессе ваши смысловые намерения для шага 4 ( "полностью включить в B каждое изменение, которое было сделано для A в № 2" ) были обмануты до нескольких байтов чистой логики ( "дать B следующее новое содержимое + кредит для обработки # 2" ). Несмотря на неудачу, это "просто" проблема UX/образования. Люди становятся намного злее, когда Правила слияния делают плохие предположения, которые приводят к потере кода и потери данных. Напротив, все, что вам нужно сделать, это нажать кнопку.

FWIW, есть много других окончаний этой истории. Если на шаге 4 вы выбрали "Копировать из источника" [aka AcceptTheirs], на шаге не было бы конфликта. То же самое, если вы выбрали разрешение AcceptMerge, но произошло с фиксацией файла с тем же самым хэшем MD5, что и A\foo.cs; 2, Если вы выбрали Keep Target [aka AcceptYours], последствия последующего изменения снова изменились, хотя я не могу вспомнить детали прямо сейчас. Все вышеперечисленное становится довольно сложным, когда вы добавляете другие параметры changetpes (особенно Rename), объединяете ветки, которые намного более не синхронизированы, чем в моем примере, вишня выбирает определенные диапазоны версий и обменивается с сиротами позже и т.д....


РЕДАКТИРОВАТЬ: по мере того как судьба имела бы это, кто-то другой просто задал тот же самый вопрос на форуме MSDN. Как правило, я натура, я написал им еще один длинный ответ, который получился совершенно другим! (хотя, очевидно, касаясь одних и тех же ключевых моментов) Надеюсь, что это поможет: http://social.msdn.microsoft.com/Forums/en-US/tfsversioncontrol/thread/e567b8ed-fc66-4b2b-a330-7c7d3a93cf1a

Ответ 2

Это случилось со мной раньше. Когда TFS объединяет Experimental to Current, он делает это, используя рабочие области на вашем жестком диске. Если текущее рабочее пространство устарело на вашем локальном компьютере, TFS получит конфликты слияния.

(Экспериментальный по HD)!= (Ток в TFS)!= (Старый ток на HD)

Попробуйте принудительно получить Current, чтобы обновить локальную копию Current и повторите попытку слияния.

Ответ 3

У вас, вероятно, есть строки, подобные этому, прежде чем вы начнете слияние...

  • Основная ветвь - содержит код A, B, C
  • Текущая ветка - содержит коды A, B, C, D, E
  • Экспериментальная ветвь - содержит коды A, B, C, D, F, G, H

Когда вы нажимаете "Current to Exp", вы объединяете функцию E в экспериментальную ветвь.

Когда вы затем переходите от Exp к Current, вам все равно придется объединять F, G и H. Вот где ваши конфликты, скорее всего, связаны корнями.

---- Ответ на 1-й комментарий ---- Вы автоматически объединяетесь или используете инструмент слияния? Что является примером того, что находится в конфликте?