Как svn merge
Работы
Команда svn merge
используется несколькими различными способами, но в основном она всегда делает две вещи в последовательности: 1) создать диф путем сравнения двух источников, и 2) применять этот diff к цели.
Два источника и цель указаны аргументами командной строки, хотя во многих случаях один или несколько аргументов могут быть опущены, если merge
может неявно определять, какими они должны быть.
В общем, то, командная строка вызова имеет вид
$ svn merge [create diff] [apply to target]
Более подробно,
1) [создать дифференциал]
svn merge
сравнивает источник А и источник B для создания diff, который представляет собой набор инструкций, необходимых для преобразования источника A в источник B.
Источниками могут быть любые элементы набора файлов: соединительная линия или ветвь, поддерево каталога или отдельный файл. Источником может быть либо элемент рабочей копии (в этом случае он идентифицируется по его файловому пути), либо элемент самого хранилища (в этом случае он идентифицируется URL-адресом репо). Источник может ссылаться на любую ревизию репозитория; если ревизия не указана, обычно предполагается самая последняя ревизия (HEAD).
2) [обратиться к целевой]
После дифф создается, merge
затем применить этот набор инструкций к цели. Цель должна быть быть элементом рабочей копии; команда merge
обычно считается выполненной из этой рабочей копии.
Очевидно, что если цель не имеет никакого отношения к двум источникам, используемым для создания диф, то вы просто получите нонсенс, когда дифференциалов инструкции к нему применяются. Цель также должна быть тем же «типом вещей», что и два источника; то есть, если diff сравнивает две ветви или ветку/туловище, то цель также должна быть либо ветвью, либо туловищем. Если этими двумя источниками являются файлы, то целью должен быть файл и т. Д.
Именно поэтому команды merge
должны быть сконструированы тщательно. Не слишком сильно потейте, потому что цель должна быть элементом вашей рабочей копии, merge
может повлиять только на рабочую копию, а не на репо. Пока вы не commit
, не проверяя результат merge
, достаточно легко исправить, если вы ошиблись merge
.
Обратный сливается
А «обратного слияния», чтобы вернуться файл является формой cherry-pick merge, который принимает два различных ревизий одного элемента в виде двух его источников. Таким образом, мы указываем только одно имя источника в командной строке, сопровождаемое -r
или -c
флагами, чтобы сказать, какие из двух версий будут источниками.
Флаг -r
определяет его как абсолютное число N
или как диапазон N:M
.
Флаг -c
указывает изменение сделана ревизия. Это полезно в некоторых случаях, но не в этом, потому что разница между текущим файлом (rev 30) и желаемым файлом (rev 10) охватывает множество изменений более чем в 20 разных версиях - я не хочу возвращать одно изменение, но целых двадцать!
С точки зрения моей гипотетической samplefile.txt
,
[create diff] = -r 10:30 <URL of repository>/path/to/samplefile.txt
производит набор инструкций, преобразующая [email protected]
к [email protected]
. Это не то, что я хочу, однако - я хочу наоборот, набор инструкций, который принимает текущий [email protected]
обратно в [email protected]
. Это может быть определено путем изменения числа оборотов, т.е.
[create diff] = -r 30:10 <URL of repository>/path/to/samplefile.txt
Это то, что делает его «обратного слияния». (Обратите внимание, что флаг -r
не имеет ничего общего со словом «reverse».)
Моя цель файл samplefile.txt
в моей рабочей копии, или
[apply to target] = WC_root/filepath/to/samplefile.txt
Поскольку дифф построен принять [email protected]
->[email protected]
, копия в моей рабочей копии должна быть последняя версия (оборот 30). Это важно проверить, потому что я ранее обновлял файл до версии 10 в интуитивно понятной, но по какой-то причине бесполезной попытке передать этот контент обратно в репозиторий как ревизию 31. Итак, всегда обязательно перед merge
команда.
Откат файл с помощью обратного слияния
Ввод [create diff]
и [apply to target]
вместе, команда для возврата samplefile.txt
из его содержания оборотов 30 к его содержанию оборотов 10 с использованием обратного слияния является
$ svn update
$ svn merge -r 30:10 <URL of repository>/path/to/samplefile.txt WC_root/filepath/to/samplefile.txt
Если все проверяется, а текущее содержимое samplefile.txt
действительно соответствует редакции 10, то я теперь передаю репо:
$ svn commit -m "reverting file to rev 10" WC_root/filepath/to/samplefile.txt
чтобы заблокировать восстановление файла в интересах других разработчиков.
Ссылки:
Лучшая общая документация я мог бы найти о том, как merge
команда определяется дается в SVN книгу здесь: Merge Syntax
Ручные секции, соединенные @bahrep дать несколько примеров о том, как вы можете использовать merge
для выполнения различных задач. (Я не могу повторить ссылки здесь, потому что это меня лишает 2-х лимитный лимит.)
И, конечно, есть svn help merge
, что будет намного понятнее после прочтения этих ссылок (и, надеюсь, этот ответ).
Большое спасибо @alroc и @bahrep за то, что помогли мне разобраться в этом!
Возможный дубликат [Лучший способ вернуться к предыдущей версии файла SVN?] (Http://stackoverflow.com/questions/345997/better-way-to-revert-to-a-previous-svn- rev-a-file) – alroc
@ alroc Спасибо, я не мог этого найти! Хотя мой вопрос по существу тот же, что и у этого искателя, я не понимаю ни одного из ответов, большинство, если не все из них касаются «обратного слияния». Кажется, что искатель соглашается с тем, что обратное слияние является неудовлетворительным решением, хотя они и приняли ответ. Ответ @ twm здесь, с другой стороны, не найден ни в одном из ответов в вашей ссылке, и, похоже, именно то, что я ищу, если оно работает (я буду проверять его завтра, чтобы убедиться). – PiotrChernin
Обратное слияние * - это самое правильное решение, поэтому вам нужно потратить время, чтобы понять, как это работает. См. Также ответ bahrep ниже, поскольку он связан с соответствующим разделом руководства. – alroc