У меня есть два потока: Source
и Target
. В какой-то момент на Source
был создан файл под названием FileA
. Затем был создан целевой поток, ответвленный от Source
. FileA
на Source
затем был переименован в FileB
.
Теперь мне нужно объединить это изменение с Target
. Результатом должно быть FileA
при переименовании Target
в FileB
.
Обычно я могу объединить один файл, используя p4 integrate
и указав fromFiles
и toFiles
.
Этот рабочий процесс прерывается для файлов, отмеченных move/delete
. Я получаю сообщение об ошибке, в котором говорится следующее:
move/delete(s) must be integrated along with matching move/add(s)
Хорошо, тогда я посмотрю, что это была за цель move/add
, и добавлю ее в команду. Но вот в чем поворот. p4 integrate
позволяет ориентироваться на несколько файлов только с помощью их системы спецификаций файлов. Я не могу указать два отдельных файла, если только они не имеют общего пути, что не всегда должно иметь место в приведенной выше ситуации.
Но еще не вся надежда потеряна, поскольку вместо явного указания fromFiles
и toFiles
в p4 integrate
вы можете вместо этого использовать branch mapping
. Там вы можете указать любое количество сопоставлений, поэтому я могу явно добавить как пару move/delete
, так и пару move/add
. Проблема решена, да?
Нет, потому что это также не работает, потому что принудительное выполнение, кажется, обрабатывает branch mapping
построчно, поэтому, как только он достигает первой строки, он выдает ту же ошибку. Даже если я поменяю порядок, поставив пару move/add
перед парой move/delete
, он все равно будет жаловаться.
Неужели невозможно интегрировать однократное переименование из одного потока в другой, если файлы переименовываются совсем во что-то другое? Как мне с этим справиться?
В большинстве случаев вы можете просто интегрировать перемещение/добавление; пока исходное сопоставление ветвей достаточно простое (а для потоков это обычно так), соответствующее перемещение/удаление будет обнаружено автоматически. Указание полного сопоставления ветвей строго необходимо только в том случае, если это что-то сложное (например, если отдельные пути в источнике сопоставляются с разными путями в целевом объекте, и файл был перемещен между этими путями).
Вот ошибка при попытке объединить FileA
самостоятельно:
C:\Perforce\karl>p4 merge --from Source FileA
Move/delete(s) must be integrated along with matching move/add(s).
а здесь мы просто объединяем FileB
сам по себе:
C:\Perforce\karl>p4 merge --from Source FileB
//stream/Target/FileA#1 - integrate from //stream/Source/FileB#1 (remapped from //stream/Target/FileB)
... must resolve content from //stream/Source/FileB#1
... must resolve move to //stream/Target/FileB
Обратите внимание: когда мы сказали, что хотим объединить FileB
, p4 смог выяснить, что он связан с FileA
, и поэтому мы открываем FileA
для интеграции, одновременно планируя разрешение имени файла. Тогда решаем:
C:\Perforce\karl>p4 resolve
c:\Perforce\karl\FileA - merging //stream/Source/FileB#1
Diff chunks: 0 yours + 0 theirs + 0 both + 0 conflicting
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) at: a
//bob-dvcs-1709920089/FileA - copy from //stream/Source/FileB
c:\Perforce\karl\FileA - resolving move to //stream/Target/FileB
Filename resolve:
at: //stream/Target/FileB
ay: //stream/Target/FileA
Accept(a) Skip(s) Help(?) at: a
//stream/Target/FileB - moved from //stream/Target/FileA
(Я также мог бы просто нажать p4 resolve -as
здесь, чтобы сделать это автоматически, но тогда мы бы не получили предварительный просмотр отдельных действий по разрешению.)
Теперь файл открыт для перемещения в потоке Target
:
C:\Perforce\karl>p4 opened
//stream/Target/FileA#1 - move/delete default change (text)
//stream/Target/FileB#1 - move/add default change (text)
C:\Perforce\karl>p4 resolved
c:\Perforce\karl\FileB - copy from //stream/Source/FileB#1
c:\Perforce\karl\FileB - moved from //stream/Target/FileA#1
c:\Perforce\karl\FileB - resolved move (copy from //stream/Target/FileB)
Другим вариантом было бы объединение по списку изменений (при условии, что в этом списке изменений не было кучи других вещей, которых мы специально хотели избежать):
C:\Perforce\karl>p4 revert //...
//stream/Target/FileA#1 - was move/delete, reverted
//stream/Target/FileB#none - was move/add, deleted
C:\Perforce\karl>p4 filelog //stream/Source/fileB
//stream/Source/FileB
... #1 change 4 move/add on 2024/03/08 by bob@bob-dvcs-1709920089 (text) 'moveB'
... ... moved from //stream/Source/FileA#1
//stream/Source/FileA
... #1 change 2 add on 2024/03/08 by bob@bob-dvcs-1709920089 (text) 'addA'
... ... moved into //stream/Source/FileB#1
... ... branch into //stream/Target/FileA#1
C:\Perforce\karl>p4 merge --from Source @4,4
//stream/Target/FileA#1 - integrate from //stream/Source/FileB#1 (remapped from //stream/Target/FileB)
... must resolve content from //stream/Source/FileB#1
... must resolve move to //stream/Target/FileB
Список изменений 4, конечно, будет включать в себя как перемещение/удаление, так и перемещение/добавление (поскольку перемещения гарантированно будут атомарными), так что это еще один способ убедиться, что вы выбираете обе версии. Если в файл были внесены другие изменения до или после перемещения, интеграция по списку изменений («выбор списка изменений») позволит избежать объединения этих изменений.