Хотя Subversion имеет множество возможностей, опций и украшательств, в каждодневной практике используются только некоторые из них. В этом разделе мы пройдемся по задачам, наиболее часто выполняемым в течение рабочего дня.
Типичный рабочий цикл выглядит примерно так:
Обновление рабочей копии
svn update
Внесение изменений
svn add
svn delete
svn copy
svn move
Анализ изменений
svn status
svn diff
svn revert
Слияние изменений, выполненных другими, с вашей рабочей копией
svn update
svn resolved
Фиксация изменений
svn commit
При командной работе над проектом обновление рабочей копии необходимо для получения любых изменений, внесенных другими разработчиками проекта с момента вашего последнего обновления. Используйте svn update для синхронизации вашей рабочей копии с последней правкой в хранилище.
$ svn update U foo.c U bar.c Updated to revision 2.
В данном случае, кто-то другой зафиксировал изменения в файлах
foo.c
и bar.c
после
вашего последнего обновления, и Subversion обновила вашу рабочую
копию, включив эти изменения.
Рассмотрим поподробнее информацию, выводимую командой svn update. Когда сервер отправляет изменения в вашу рабочую копию, для каждого элемента выводится латинская буква — код, определяющий действие, выполненное Subversion для приведения вашей рабочей копии в актуальное состояние:
U foo
Файл foo
был
U
pdated — обновлен
(получил изменения с сервера).
A foo
Файл или каталог foo
был
A
dded — добавлен в
рабочую копию.
D foo
Файл или каталог foo
был
D
eleted — удален
из рабочей копии.
R foo
Файл или каталог foo
был
R
eplaced — заменен
в рабочей копии; это значит, что foo
был удален, а новый элемент с таким же именем был добавлен.
Несмотря на то, что они могут иметь одинаковое имя,
хранилище рассматривает их как разные объекты с
отдельной историей.
G foo
Файл foo
получил новые изменения
из хранилища, однако ваша локальная копия в то же время содержит
ваши собственные изменения. Изменения, полученные из хранилища,
либо не пересекаются, либо они точно такие же как ваши локальные
изменения, поэтому Subversion успешно выполнила
merG
ed — слияние
изменений хранилища с файлом.
C foo
Файл foo
получил от сервера
C
onflicting —
конфликтующие изменения. Изменения с сервера пересекаются с
вашими изменениями файла. Однако это не повод для паники. Такое
перекрытие просто нуждается в разрешении человеком (вами); мы
обсудим эту ситуацию позднее в этой главе.
Теперь вы можете приступать к делу и вносить изменения в рабочую копию. Как правило, целесообразнее всего работать отдельно по каждому частному изменению (или набору изменений), такому как реализация новой функциональной возможности, исправление ошибки и т. п. Здесь вы будете пользоваться такими командами Subversion как svn add, svn delete, svn copy и svn move. Однако, если вы просто редактируете файлы, которые уже находятся под контролем Subversion, ни одна из этих команд вам не нужна. В своей рабочей копии вы можете делать следующие изменения:
Это самый простой вид изменений. Вам не нужно сообщать Subversion о своем намерении изменить файл; просто берите и вносите изменения. Subversion сможет автоматически определить измененные файлы.
Вы можете попросить Subversion «отметить» файлы и каталоги для удаления, добавления, копирования или перемещения. Хотя эти изменения сразу же отразятся в рабочей копии, в хранилище не произойдет ни добавления, ни удаления до тех пор, пока вы не выполните фиксацию изменений.
Для внесения изменений в файлы используйте свой текстовый редактор, текстовый процессор, графическую программу или любой другой инструмент, который вы обычно используете. Subversion обрабатывает бинарные файлы так же легко как и текстовые — и настолько же эффективно.
Рассмотрим четыре подкоманды Subversion, которые вы чаще всего будете использовать при внесении изменений в структуру (команды svn import и svn mkdir мы рассмотрим позже).
Внимание | |
---|---|
Хотя вы можете редактировать файлы любыми программными средствами, не следует менять структуру рабочей копии, не проинформировав о своих действиях Subversion. Для изменения структуры рабочей копии используйте команды svn copy, svn delete и svn move, а для добавления новых файлов и каталогов под контроль версий используйте svn add. |
Запланировать файл, каталог или символьную ссылку
foo
для добавления в хранилище.
При следующей фиксации foo
станет
компонентом своего родительского каталога. Обратите внимание
на то, что если foo
является каталогом,
то все содержащееся в foo
будет
запланировано для добавления. Чтобы добавить отдельно только
сам каталог foo
, воспользуйтесь параметром
--non-recursive
(-N
).
Запланировать удаление из хранилища файла, каталога
или символьной ссылки foo
. Если
foo
является файлом или ссылкой,
он сразу же удаляется из вашей рабочей копии. Если
foo
является каталогом, он не
удаляется, но Subversion запланирует его удаление.
foo
будет удален из рабочей копии и
хранилища при фиксации изменений.[8]
Создать новый элемент bar
как
копию foo
. bar
будет автоматически запланирован для добавления.
Когда при следующей фиксации bar
будет добавлен в хранилище, в его истории будет отмечено
копирование (то, что первоисточником является
foo
). svn copy не
создает промежуточных каталогов.
Эта команда полностью аналогична выполнению
svn copy foo bar; svn delete foo.
Поэтому, bar
будет запланирован для
добавления как копия foo
, а
foo
будет запланирован для удаления.
svn move не создает промежуточных
каталогов.
После внесения изменений вы должны зафиксировать их в хранилище, но перед этим было бы неплохо посмотреть, что же, собственно, вы изменили. Проанализировав перед фиксацией свои изменения, вы сможете составить более аккуратное лог-сообщение. Кроме того, вы можете обнаружить, что изменили файл непреднамеренно, что позволит еще до фиксации вернуть файл к предыдущему состоянию. К тому же, это хорошая возможность пересмотреть и проверить изменения перед их публикацией. Чтобы увидеть все сделанные изменения, вы можете воспользоваться svn status, svn diff и svn revert. Первые две команды вы можете использовать для того, чтобы найти измененные файлы рабочей копии, а затем, при помощи третьей, отменить некоторые (или все) изменения.
Subversion была оптимизирована для решения такой задачи
и способна выполнять множество действий без обращения к
хранилищу. В частности, рабочая копия содержит в
.svn
-области скрытую кэшированую
«нетронутую» копию каждого версионированного файла.
За счет этого Subversion может быстро показать, как изменились
ваши рабочие файлы или даже предоставить, не связываясь с хранилищем,
возможность откатить изменения.
Наверное, команду svn status вы будете использовать чаще, чем любую другую команду Subversion.
При запуске svn status без параметров из
корневого каталога рабочей копии будут найдены все сделанные вами
изменения файлов и структуры. Ниже приведены примеры различных
буквенных кодов, возвращаемых svn status.
(Обратите внимание, что текст, следующий за
#
, на самом деле svn status не
печатает.)
L some_dir # svn оставила блокировку в .svn-области для some_dir M bar.c # содержимое bar.c имеет локальные изменения M baz.c # в baz.c есть изменения в свойствах, а в содержимом нет X 3rd_party # каталог является частью внешней зависимости ? foo.o # svn не управляет foo.o ! some_dir # svn управляет этим элементом, но он отсутствует или поврежден ~ qux # элемент версионировался как файл/каталог/ссылка, но тип был изменен I .screenrc # svn не управляет этим элементом и настроена на его игнорирование A + moved_dir # добавлен с историей своего происхождения M + moved_dir/README # добавлен с историей и имеет локальные изменения D stuff/fish.c # файл запланирован для удаления A stuff/loot/bloo.h # файл запланирован для добавления C stuff/loot/lump.c # файл имеет текстовый конфликт с момента обновления C stuff/loot/glub.c # файл имеет конфликт в свойствах с момента обновления R xyz.c # файл запланирован для замены S stuff/squawk # файл или каталог были переключены на ветку K dog.jpg # файл заблокирован локально; присутствует маркер блокирования O cat.jpg # файл заблокирован в хранилище другим пользователем B bird.jpg # файл заблокирован локально, но блокировка была нарушена T fish.jpg # файл заблокирован локально, но блокировка была снята
svn status печатает пять колонок букв, затем несколько пробелов, затем имя файла или каталога. Первая колонка показывает статус файла или каталога и/или ее содержимого. При этом используются следующие коды:
A item
Файл, каталог или символьная ссылка
item
был запланирован для
добавления в хранилище.
C item
Файл item
находится в
состоянии конфликта. Это означает, что изменения,
полученные от сервера, при обновлении пересекаются
с локальными изменениями, имеющимися в рабочей копии.
Перед фиксацией изменений вам необходимо разрешить
этот конфликт.
D item
Файл, каталог или символьная ссылка
item
запланирован
для удаления из хранилища.
M item
Содержимое файла item
было
изменено.
R item
Файл, каталог или символьная ссылка запланирован
для замены item
в хранилище.
Это значит, что сначала объект был удален, а затем
другой объект с таким же именем был добавлен, все в одной
правке.
X item
Каталог item
не версионирован,
но относится к внешним зависимостям Subversion. Более подробно
о внешних зависимостях см. в «Внешние зависимости».
? item
Файл, каталог или символьная ссылка не находится под
контролем версий. Вы можете убрать знаки вопроса либо
воспользовавшись параметром --quiet
(-q
) команды svn status,
либо установив свойство svn:ignore
родительского каталога. Дополнительную информацию об
игнорировании файлов см. в «Пропуск неверсионированных элементов».
! item
Файл, каталог или символьная ссылка
item
находится под контролем версий,
но отсутствует в рабочей копии или поврежден. Элемент
может отсутствовать, если он был удален без использования
команд Subversion. В частном случае, каталог может оказаться
поврежденным, если вы прервали создание рабочей копии или
обновление. Быстрый запуск svn update
заново вытащит файл или каталог из хранилища, либо
svn revert file восстановит отсутствующий
файл.
~ item
Файл, каталог или символьная ссылка
item
в хранилище является объектом
одного типа, а то, что на самом деле находится в рабочей
копии, является чем-то другим. Например, в хранилище
Subversion может иметь файл, а вы удалили файл и создали
на его месте каталог, не используя для этого команды
svn delete или
svn add.
I item
Файл, каталог или символьная ссылка
item
находится под контролем
версий, и Subversion настроена на его игнорирование
при операциях svn add, svn
import и svn status.
Дополнительную информацию об игнорированных файлах см. в
«Пропуск неверсионированных элементов».
Обратите внимание на то, что этот символ появляется
при использовании опции --no-ignore
для svn status — иначе
файл игнорируется и не показывается вообще!
Вторая колонка показывает статус свойств файлов и
каталогов (подробнее о свойствах см. в «Свойства»). Если во второй колонке
показывается M
, свойства
были изменены. Если в этой колонке показывается
C
, то это означает, что свойства
файла находятся в состоянии конфликта, который должен быть
разрешен до фиксации изменений в хранилище. Во всех других случаях
будет выведен пробел.
Третья колонка может содержать только пробел или
L
, это значит, что у каталога
заблокирована рабочая область .svn
.
Вы увидите L
, если запустите
svn status в каталоге, в котором выполняется
svn commit — например, когда вы
редактируете лог-сообщение.
Четвертая колонка может содержать только пробел или
+
, это означает, что
элемент был запланирован для «добавления с историей».
Это может быть файл или корень скопированного каталога.
+
означает, что элемент
является частью поддерева, запланированного для
«добавления с историей», т. е. один из родительских
каталогов был скопирован, и этот элемент просто его часть.
M +
означает, что
элемент является частью поддерева, запланированного для
«добавления с историей», и
имеет локальные изменения. При выполнении фиксации вначале
будет «добавлен с историей» родительский каталог,
что означает автоматическое наличие файла в копии.
После этого в копию будут загружены локальные изменения.
Пятая колонка может содержать только пробел или
S
. Это означает,
что файл или каталог был переключен с пути остальной
рабочей копии на ветку (используя svn switch).
Шестая колонка показывает информацию о блокировках,
которые подробно рассмотрены в «Locking». (Это не те блокировки, которые
отмечаются L
в третьей колонке;
см. Three meanings of «lock»)
Если вы укажете конкретный путь для svn status, то получите информацию только об этом элементе:
$ svn status stuff/fish.c D stuff/fish.c
Кроме того, svn status имеет
параметр --verbose
(-v
),
который покажет вам статус каждого
элемента в рабочей копии, даже если он не менялся:
$ svn status --verbose M 44 23 sally README 44 30 sally INSTALL M 44 20 harry bar.c 44 18 ira stuff 44 35 harry stuff/trout.c D 44 19 ira stuff/fish.c 44 21 sally stuff/things A 0 ? ? stuff/things/bloo.h 44 36 harry stuff/things/gloo.c
Это «длинная форма» представления вывода svn status. Первая колонка осталась та же самая, а вот вторая колонка показывает рабочую правку элемента. Третья и четвертая колонки показывают правку, в которой элемент последний раз изменялся и автора этих изменений.
Ни один из указанных выше вызовов svn
status не обращается к хранилищу, они работают
только локально, сравнивая метаданные каталога
.svn
с рабочей копией. Отметим, что есть
параметр --show-updates
(-u
),
указывающий на соединение с хранилищем и добавляющий
информацию об устаревании элементов:
$ svn status --show-updates --verbose M * 44 23 sally README M 44 20 harry bar.c * 44 35 harry stuff/trout.c D 44 19 ira stuff/fish.c A 0 ? ? stuff/things/bloo.h Status against revision: 46
Обратите внимание на две звездочки: если сейчас вы
запустите svn update вы получите изменения
для README
и trout.c
.
Это очень полезная информация — перед фиксацией вам необходимо
обновить и получить изменения с сервера для
README
, или же хранилище отклонит вашу фиксацию
как не соответствующую актуальному состоянию. (Подробнее об этом
чуть позже.)
Еще один механизм для анализа изменений — это команда svn diff. Запустив svn diff без аргументов, можно увидеть, какие именно изменения вы внесли, в результате будут выведены изменения файлов в едином формате представления различий:[9]
$ svn diff Index: bar.c =================================================================== --- bar.c (revision 3) +++ bar.c (working copy) @@ -1,7 +1,12 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <stdio.h> int main(void) { - printf("Sixty-four slices of American Cheese...\n"); + printf("Sixty-five slices of American Cheese...\n"); return 0; } Index: README =================================================================== --- README (revision 3) +++ README (working copy) @@ -193,3 +193,4 @@ +Note to self: pick up laundry. Index: stuff/fish.c =================================================================== --- stuff/fish.c (revision 1) +++ stuff/fish.c (working copy) -Welcome to the file known as 'fish'. -Information on fish will be here soon. Index: stuff/things/bloo.h =================================================================== --- stuff/things/bloo.h (revision 8) +++ stuff/things/bloo.h (working copy) +Here is a new file to describe +things about bloo.
Команда svn diff формирует
свой вывод, сравнивая ваши рабочие файлы с кэшированными
«нетронутыми» копиями из .svn
.
Весь текст запланированных для добавления файлов показывается
как добавленный, а весь текст запланированных
для удаления файлов показывается как удаленный.
Вывод происходит в едином формате представления
различий. При этом удаленные строки предваряются
знаком -
, а добавленные — знаком
+
. Кроме этого svn diff
печатает имена файлов и информацию о сдвиге информации, которая
необходима программе patch, и, следовательно,
вы можете получать «патчи», перенаправив вывод
различий в файл:
$ svn diff > patchfile
Вы можете, например, отправить по электронной почте файл патча другому разработчику для ознакомления или тестирования перед фиксацией.
Теперь предположим, что, просмотрев вывод команды diff,
вы обнаружили, что изменения в README
ошибочны — к примеру, потому, что в своем редакторе
вы случайно набрали текст, предназначавшийся для другого
файла.
В такой ситуации как нельзя кстати окажется команда svn revert.
$ svn revert README Reverted 'README'
Subversion возвращает файл в состояние, предшествующее
модификации, путем замены файла его кэшированной
«первоначальной» копией из
.svn
-области. Кроме того, обратите внимание,
что svn revert может отменить
любые запланированные операции —
например, вы можете прийти к решению всё-таки не добавлять новый
файл:
$ svn status foo ? foo $ svn add foo A foo $ svn revert foo Reverted 'foo' $ svn status foo ? foo
Замечание | |
---|---|
svn revert
|
Или, допустим, вы ошибочно удалили файл из-под контроля версий:
$ svn status README README $ svn delete README D README $ svn revert README Reverted 'README' $ svn status README README
Мы уже видели, как svn status -u может предупредить о конфликтах. Предположим, вы запустили svn update и увидели кое-что интересное:
$ svn update U INSTALL G README C bar.c Updated to revision 46.
Коды U
и
G
интереса не представляют;
эти файлы без проблем поглотили изменения из хранилища.
Файлы, отмеченные U
, локальных
изменений не содержат и были U
pdated
— обновлены изменениями из хранилища. Отмеченные
G
были
merG
ed — слиты, это значит, что
файл имел локальные изменения, но изменения, пришедшие из хранилища,
не перекрываются с локальными изменениями.
А вот файлы, отмеченные C
,
имеют конфликт. Это значит, что изменения с сервера пересеклись
с вашими личными, и теперь вам нужно вручную сделать между ними
выбор.
Всякий раз, когда возникает конфликт, в его обнаружении и разрешении вам, как правило, помогают три вещи:
Subversion печатает C
во время обновления и запоминает, что файл в состоянии
конфликта.
Если Subversion считает, что тип файла допускает
слияние изменений, она включает в него
маркеры конфликта —
специальные текстовые строки, отделяющие
«стороны» конфликта —
чтобы визуально показать пересекающиеся области.
(Subversion использует свойство svn:mime-type
для определения возможности контекстного, построчного слияния.
См. «Тип содержимого файла»
для более подробной информации.)
Для каждого конфликтного файла Subversion добавляет в рабочую копию до трех не версионированных дополнительных файлов:
filename.mine
Это ваш файл в том виде, в каком он присутствовал в
рабочей копии до обновления — без маркеров
конфликта. Этот файл содержит в себе только ваши изменения
и ничего больше. (Если Subversion решает, что файл не
пригоден для слияния изменений, то файл .mine
не создается, так как он будет идентичным рабочему
файлу.)
filename.rOLDREV
Это файл правки BASE
, где
BASE
— правка, которая была до
обновления рабочей копии. Иными словами, это файл, который
был у вас до внесения изменений.
filename.rNEWREV
Это файл, который ваш Subversion-клиент
получил с сервера при обновлении
рабочей копии. Этот файл соответствует правке
HEAD
хранилища.
Здесь OLDREV
— это номер правки
файла в каталоге .svn
, а
NEWREV
— номер правки
HEAD
хранилища.
Например, Салли внесла изменения в файл
sandwich.txt
из хранилища. Одновременно Гарри
изменил файл в своей рабочей копии и зафиксировал
его. Салли обновляет свою рабочую копию перед фиксацией и получает
конфликт:
$ svn update C sandwich.txt Updated to revision 2. $ ls -1 sandwich.txt sandwich.txt.mine sandwich.txt.r1 sandwich.txt.r2
Теперь Subversion не позволит зафиксировать
файл sandwich.txt
, пока не будут удалены три
временных файла.
$ svn commit --message "Add a few more things" svn: Commit failed (details follow): svn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict
Для разрешения конфликта у вас есть три варианта:
Объединить конфликтующий текст «вручную» (путем анализа и редактирования маркеров конфликта в файле).
Скопировать один из временных файлов поверх своего рабочего файла.
Выполнить svn revert <filename> для отказа от всех ваших локальных изменений.
После разрешения конфликта вам нужно известить об этом Subversion, выполнив svn resolved. Эта команда удалит три временных файла, и Subversion больше не будет считать, что файл находится в состоянии конфликта. [10]
$ svn resolved sandwich.txt Resolved conflicted state of 'sandwich.txt'
Слияние конфликтов вручную может показаться пугающим, когда вы делаете это в первый раз, но после небольшой практики станет для вас таким же простым, как езда на велосипеде.
Возьмем пример. По недоразумению вы и ваш соразработчик Салли
одновременно редактируете файл sandwich.txt
.
Салли зафиксировала свои изменения, и поэтому при обновлении
своей рабочей копии вы получите конфликт, для разрешения которого
вам необходимо отредактировать sandwich.txt
.
Для начала посмотрим на файл:
$ cat sandwich.txt Top piece of bread Mayonnaise Lettuce Tomato Provolone <<<<<<< .mine Salami Mortadella Prosciutto ======= Sauerkraut Grilled Chicken >>>>>>> .r2 Creole Mustard Bottom piece of bread
Строки, начинающиеся со знаком «меньше чем», «равно» и «больше чем», являются маркерами конфликта. Перед следующей фиксацией вам нужно будет убедиться, что они удалены из файла. Текст между первыми двумя маркерами состоит из ваших изменений в конфликтующей области:
<<<<<<< .mine Salami Mortadella Prosciutto =======
Текст между вторым и третьим маркером конфликта — это текст из фиксации Салли:
======= Sauerkraut Grilled Chicken >>>>>>> .r2
Скорее всего вы не захотите просто удалить маркеры конфликта и изменения, сделанные Салли, — она ужасно удивится, когда дойдет до сандвича и не увидит того, что ожидала. Это как раз тот случай, когда вы снимаете трубку или пересекаете офис и объясняете Салли, что не можете получить из итальянского гастронома квашеную капусту. [11] После того, как вы согласуете изменения, нужно будет выполнить фиксацию. Для этого отредактируйте ваш файл и удалите маркеры конфликта.
Top piece of bread Mayonnaise Lettuce Tomato Provolone Salami Mortadella Prosciutto Creole Mustard Bottom piece of bread
Теперь выполните svn resolved, и вы готовы к фиксации изменений:
$ svn resolved sandwich.txt $ svn commit -m "Go ahead and use my sandwich, discarding Sally's edits."
Обратите внимание на то, что svn resolved, в отличие от большинства команд, с которыми мы имели дело в этой главе, требует аргумент. В любом случае будьте осторожны и выполняйте svn resolved тогда, когда вы убеждены, что исправили конфликт в файле. После того как временные файлы будут удалены, Subversion позволит вам зафиксировать файл, даже если он все еще содержит маркеры конфликта.
Если вы испытываете затруднения при редактировании конфликтующего файла, всегда можно обратиться к тем трем файлам, которые Subversion создает в рабочей копии — включая ваш файл в том виде, в каком он был до обновления. Для анализа этих трех файлов вы даже можете воспользоваться программами для слияния изменений от сторонних разработчиков.
Если вы получили конфликт и решили отказаться от своих изменений, вы можете просто скопировать один из временных файлов, созданных Subversion, поверх файла в рабочей копии:
$ svn update C sandwich.txt Updated to revision 2. $ ls sandwich.* sandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1 $ cp sandwich.txt.r2 sandwich.txt $ svn resolved sandwich.txt
Если вы получили конфликт и, проанализировав, решили отбросить изменения и начать сначала, просто отмените ваши изменения:
$ svn revert sandwich.txt Reverted 'sandwich.txt' $ ls sandwich.* sandwich.txt
Обратите внимание, что при возврате конфликтующего файла к исходному состоянию вам не нужно выполнять svn resolved.
Наконец-то! Вы закончили с редактированием, слили все изменения с сервера и готовы к тому, чтобы зафиксировать их в хранилище.
Команда svn commit отправляет все ваши
изменения в хранилище. При фиксации изменений необходимо описать
ваши изменения в тексте лог-сообщения.
Лог-сообщение будет присоединено к созданной правке. Если ваше
лог-сообщение короткое, вы можете указать его в командной строке,
используя опцию --message
(или
-m
):
$ svn commit --message "Corrected number of cheese slices." Sending sandwich.txt Transmitting file data . Committed revision 3.
Однако, если вы заранее составляли лог-сообщение в процессе
работы, можно попросить Subversion взять его из файла,
передав имя этого файла в параметре --file
:
$ svn commit --file logmsg Sending sandwich.txt Transmitting file data . Committed revision 4.
Если вы не укажете ни опции --message
, ни
опции --file
, для составления лог сообщения
Subversion автоматически запустит ваш любимый редактор (см.
editor-cmd
в разделе
«Config»).
Подсказка | |
---|---|
Если, набирая сообщение в редакторе, вы решите отменить фиксацию, то можете просто выйти из редактора без сохранения изменений. Если вы уже сохранили сообщение, просто удалите текст и выполните сохранение еще раз. $ svn commit Waiting for Emacs...Done Log message unchanged or not specified a)bort, c)ontinue, e)dit a $ |
Хранилище, в общем-то, не знает ничего о смысле ваших изменений; оно только контролирует, чтобы никто не изменил те же файлы, что и вы. Если это все-таки случилось, вся фиксация будет отклонена, и вы получите сообщение о том, что один или несколько файлов устарели:
$ svn commit --message "Add another rule" Sending rules.txt svn: Commit failed (details follow): svn: Out of date: 'rules.txt' in transaction 'g'
В таком случае вам нужно выполнить svn update, разобраться со всеми слияниями и конфликтами и попытаться выполнить фиксацию снова.
Мы рассмотрели простейший рабочий цикл использования Subversion. В Subversion существует много других возможностей, которые вы можете применять для управления рабочей копией и хранилищем; но очень многое можно сделать, используя исключительно команды, рассмотренные в этой главе.
[8] Конечно,
ничего полностью из хранилища не удаляется — удаление
касается только HEAD
правки хранилища. Вы
можете восстановить все, что вы удалили, создав рабочую
копию (или обновив существующую) на основе более ранней
правки, чем та, в которой вы удалили элемент.
[9] Subversion
использует свой внутренний
механизм обнаружения различий, который по умолчанию использует для
вывода единый формат представления различий. Если вы хотите получить
различия в другом формате, укажите внешнюю программу поиска различий,
используя --diff-cmd
и передав любые аргументы,
которые вы хотите использовать, в параметре
--extensions
. Например, для того чтобы увидеть
контекстные локальные изменения в файле foo.c
,
игнорируя изменения в числе пробелов, запустите svn diff
--diff-cmd /usr/bin/diff --extensions '-bc' foo.c.
[10] Вы можете удалить временные файлы самостоятельно — но стоит ли это делать, если можно переложить эту работу на Subversion? Нам так не кажется.
[11] А если вы их об этом попросите, они лишь посмеются над вами.