Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab4.doc
Скачиваний:
27
Добавлен:
02.04.2015
Размер:
712.7 Кб
Скачать

3.10.2 Отмена изменений

Еще одной типичной задачей для svn merge является откат ранее сделанных изменений. Предположим, работая в копии /calc/trunk, вы вдруг выясняете, что изменения файла integer.c, сделанные в правке 303, были совершенно ошибочными. Вы можете воспользоваться командой svn merge для «отмены»изменений в своей рабочей копии, после чего зафиксировать локальные изменения в хранилище. Для этого нужно всего лишь указать различия в обратном порядке:

$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk

U integer.c

$ svn status

M integer.c

$ svn diff

# verify that the change is removed

$ svn commit -m "Undoing change committed in r303."

Sending integer.c

Transmitting file data .

Committed revision 350.

Правку хранилища можно рассматривать как группу изменений (некоторые системы управления версиями называют это набором изменений). Используя параметр -r, можно попросить svn merge применить к рабочей копии набор изменений или целый диапазон наборов изменений. В нашем примере с отменой изменений мы просим svn merge применить к рабочей копии набор изменений #303 в обратном направлении.

Обратите внимание, что подобный откат изменений ничем не отличается от остальных операций, выполняемых с помощью svn merge. Поэтому необходимо с помощью svn status и svn diff убедиться в том, что результат соответствует ожиданиям, а затем, используя svn commit, отправить финальную версию в хранилище. После фиксации этот конкретный набор изменений больше не будет отражен в правке HEAD.

Давайте, однако, подумаем: отменяется ли на самом деле предыдущая фиксация? Изменения продолжают существовать в правке 303. И если кто-то создаст рабочую копию проекта calc между правками 303 и 349, он ведь все равно получит ошибочные изменения?

Безусловно, это так. Говоря об «удалении» изменений, мы имеем в виду их удаление из правки HEAD. Исходные изменения по-прежнему останутся в истории хранилища. Чаще всего это можно рассматривать даже как положительный момент. В любом случае, большинство пользователей интересует только HEAD-правка проекта. Однако, возможны ситуации, когда необходимо полностью удалить последствия фиксации. (Например, если кто-то случайно зафиксировал конфиденциальный документ.) Сделать это будет непросто, так как архитектура Subversion намеренно исключает возможность потери информации. Правки представляют собой не меняющиеся деревья файлов, основанные друг на друге. Удаление правки из хранилища может вызвать эффект домино, потащив за собой все последующие правки и повредив все рабочие копии. [26]

3.10.3 Восстановление удаленных элементов

Отличным свойством системы управления версиями является то, что информация никогда не теряется. При удалении файла или каталога элемент исключается из правки HEAD, но продолжает существовать в более ранних правках. Новые пользователи очень часто спрашивают: «Как мне вернуть назад свой файл или каталог?»

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

В отличие от CVS, Subversion не имеет каталога Attic[27], поэтому для определения искомой пары координат восстанавливаемого объекта нужно вызвать svn log. Лучше всего запустить svn log --verbose в каталоге, который содержал удаленный объект. Параметр --verbose покажет для каждой правки список измененных элементов — в этом случае вам останется только найти ту правку, в которой файл или каталог были удалены. Это можно сделать визуально или обработав вывод команды каким-нибудь инструментом (например, утилитой grep или просто запустив поиск в редакторе).

$ cd parent-dir

$ svn log --verbose

------------------------------------------------------------------------

r808 | joe | 2003-12-26 14:29:40 -0600 (Fri, 26 Dec 2003) | 3 lines

Changed paths:

D /calc/trunk/real.c

M /calc/trunk/integer.c

Added fast fourier transform functions to integer.c.

Removed real.c because code now in double.c.

В этом примере предполагается, что вы ищете удаленный файл real.c. Просмотрев логи родительского каталога, вы можете заметить, что этот файл был удален в правке 808. Следовательно, самая последняя версия этого файла была в правке, предшествующей удалению. Вывод: необходимо из правки 807 восстановить путь /calc/trunk/real.c.

Поиск — непростая задача. Теперь, когда нам известно, что именно нужно восстановить, есть две варианта действий.

Во-первых, мы можем посредством svn merge применить правку 808 «в обратном направлении». (Как отменять изменения, мы уже рассматривали, см.«Отмена изменений».) Это приведет к повторному добавлению файла real.c в форме локального изменения. Файл будет запланирован для добавления, и после фиксации будет снова присутствовать в HEAD.

Однако, в данном примере это не самое лучшее решение. Повторное применение правки 808 не только добавит файл real.c. Лог-сообщение показывает, что также будут отменены некоторые изменения в integer.c, что весьма нежелательно. Конечно, можно выполнить обратное слияние с правкой 808, а затем отменить (svn revert) локальные изменения в integer.c, но такой подход плохо масштабируется. Что, если в правке 808 изменилось 90 файлов?

При другом, более аккуратном подходе svn merge вообще не используется, а вместо этого применяется команда svn copy. Просто скопируйте объект, заданный «парой координат» (правка и путь), из хранилища в рабочую копию:

$ svn copy --revision 807 \

http://svn.example.com/repos/calc/trunk/real.c ./real.c

$ svn status

A + real.c

$ svn commit -m "Resurrected real.c from revision 807, /calc/trunk/real.c."

Adding real.c

Transmitting file data .

Committed revision 1390.

Знак "плюс" в столбце статуса показывает, что элемент не просто запланирован для добавления, а запланирован для добавления «с историей». Subversion запоминает, откуда он был скопирован. В будущем вызов svn log для этого файла будет пересекать точку восстановления файла и прослеживать всю историю, предшествующую правке 807. Другими словами, новый файл real.c на самом деле не является новым; он является прямым потомком исходного файла, который был удален.

Хотя наш пример демонстрирует только восстановление файла, отметим, что такой же подход будет работать и при восстановлении удаленных каталогов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]