Простейший рабочий цикл
Пред. | Глава 2. Экскурсия по Subversion | След.

## Простейший рабочий цикл

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 успешно выполнила mer`G`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.

svn add foo

  Запланировать файл, директорию или символьную ссылку `foo` для добавления в хранилище. При следующей фиксации, `foo` станет компонентом своей родительской директории. Обратите внимание на то, что если `foo` является директорией, то все содержащееся в `foo` будет запланировано для добавления. Если вы хотите добавить отдельно `foo` воспользуйтесь параметром `--non-recursive` (`-N`).

svn delete foo

  Запланировать удаление из хранилища файла, директории или символьной ссылки `foo`. Если `foo` является файлом или ссылкой, он сразу же удаляется из вашей рабочей копии. Если `foo` является директорией, она не удаляется, но Subversion запланирует ее удаление. `foo` будет удалена из рабочей копии и хранилища при фиксации изменений.[8]

svn copy foo bar

  Создать новый элемент `bar` как копию `foo`. `bar` будет автоматически запланирован для добавления. Когда при следующей фиксации `bar` будет добавлен в хранилище в его истории будет отмечено копирование (то, что первоисточником является `foo`). svn copy не создает промежуточных директорий.

svn move foo bar

  Эта команда полностью аналогична выполнению svn copy foo bar; svn delete foo. Поэтому, `bar` будет запланирован для добавления как копия `foo`, а `foo` будет запланирован для удаления. svn move не создает промежуточных директорий.

### Анализ изменений

После внесения изменений вам необходимо зафиксировать их в хранилище, но перед тем, как вы это сделаете, не плохо бы посмотреть, что, собственно, вы изменили. Проанализировав перед фиксацией свои изменения, вы сможете составить более аккуратное лог-сообщение. Кроме того, вы можете обнаружить, что вы изменили файл непреднамеренно и это даст вам возможность до фиксации вернуть файл к предыдущему состоянию. К тому же, это хорошая возможность пересмотреть и проверить изменения перед их публикацией. Что бы увидеть все сделанные изменения вы можете воспользоваться svn status, svn diff и svn revert. Первые две команды вы можете использовать для того, что бы найти измененные файлы рабочей копии, а затем при помощи третьей, возможно, отменить некоторые (или все) изменения.

Subversion была оптимизирована для решения такой задачи и способна выполнять множество действий без обращения к хранилищу. В частности, в `.svn`-области рабочая копия содержит скрытую кешированую «нетронутую» копию каждого версионированного файла. Вследствие этого, Subversion может быстро показать, как изменились ваши рабочие файлы или даже предоставить, не связываясь с хранилищем, возможность сделать откат изменений.

#### svn status

Наверное, команду 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` родительской директории. Больше информации об игнорировании файлов см. в «Ignoring Unversioned Items».

`! 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. Больше информации об игнорированных файлах см. в «Ignoring Unversioned Items». Обратите внимание на то, что этот символ появляется при использовании опции `--no-ignore` для svn status — иначе файл игнорируется и не показывается вообще!

Вторая колонка показывает статус свойств файлов и директорий (больше о свойствах см. в «Свойства»). Если во второй колонке показывается `M` свойства были изменены. Если в этой колонке показывается `C` это значит, что свойства этого файла находятся в состоянии конфликта, который должен быть решен до фиксации изменений в хранилище. Во всех других случаях будет выведен пробел.

Третья колонка может содержать только пробел или `L`, это значит, что у директории заблокирована рабочая область `.svn`. Вы увидите `L` если запустите svn status в директории, в которой выполняется svn commit — например, когда вы редактируете лог-сообщение.

Четвертая колонка может содержать только пробел или `+`, это означает, что элемент был запланирован для «добавления с историей». Это может быть файл или корень скопированной директории. `+` означает, что элемент является частью поддерева запланированного для «добавления с историей», т. е. одна из родительских директорий была скопирована и этот элемент просто ее часть. `M +` означает, что элемент является частью поддерева запланированного для «добавления с историей» and имеет локальные изменения. При выполнении фиксации, в начале родительская директория будет «добавлена с историей», что означает автоматическое наличие файла в копии. После этого в копию будут загружены локальные изменения.

Пятая колонка может содержать только пробел или `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. Увидеть как именно вы изменили элементы можно запустив 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

Вы можете, например, отправить по электронной почте патч-файл другому разработчику для ознакомления или тестирования перед фиксацией.

#### svn revert

Теперь предположим, просмотрев вывод команды 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 `ITEM` будет иметь точно такой же эффект, как и удаление `ITEM` из вашей рабочей копии, а затем выполнение svn update -r BASE `ITEM`. Однако, если вы отменяете изменения для файла, 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` были mer`G`ed - слиты, это значит, что файл имел локальные изменения, но изменения, пришедшие из хранилища, не перекрываются с локальными изменениями.

А вот отмеченные `C` имеют конфликт. Это значит, что изменения с сервера пересеклись с вашими личными и теперь вам нужно вручную сделать между ними выбор.

Всякий раз когда возникает конфликт, для того, чтобы помочь вам заметить и решить этот конфликт, возникают как правило три вещи:

- Subversion печатает `C` во время обновления и запоминает, что файл в состоянии конфликта.

- Если Subversion считает, что файл объединяемого типа она помещает маркеры конфликта — специальные текстовые строки которые отделяют «стороны» конфликта — в файл, для того, чтобы визуально показать пересекающиеся области. (Subversion использует свойство `svn:mime-type` для определения возможности контекстного, построчного слияния. См. «File Content 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

Если вы получили конфликт и вместо анализированния решаете отбросить изменения и начать сначала, просто отмените ваши изменения:

    $ 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] And if you ask them for it, they may very well ride you out of town on a rail.

Пред. | Уровень выше | След.
Создание рабочей копии | Начало | Анализ истории