Accesses Repository


Only if operating on URLs



For obtaining differences against anything but BASE revision in your working copy




Only if exporting from a URL




No




Yes




Only if operating on URLs




Yes






Yes




Yes




Only if working with URLs




Only if operating on a URL




Only if operating on a URL




Only if operating on a URL




Only if operating on a URL




Only if operating on a URL




Only if operating on a URL




Only if operating on a URL




No




No




Only if using --show-updates




Yes




Yes




Yes



Alternate Names


del, remove, rm


di




None




?, h




None




None




ls




None




None




None




None




mv, rename, ren




pdel, pd




pedit, pe




pget, pg




plist, pl




pset, ps




None




None




stat, st




sw




None




up




?, h

Пред. Уровень выше След.
svnadmin dump Содержание svnadmin hotcopy


Альтернативные имена


None



praise, annotate, ann




Нет




co




Нет




ci (сокращение от «check in»; a не «co», что есть сокращение для «checkout»)




cp



Архитектура Subversion


Общий взгляд на устройство Subversion показан на рисунке 1.1, «Архитектура Subversion».

Рисунок 1.1. Архитектура Subversion

На одной стороне схемы изображено хранилище Subversion, в котором хранится информация с версиями. На противоположной стороне показана программа-клиент Subversion, которая управляет локальными отражениями различных фрагментов этих данных (также называемыми «рабочими копиями»). Между этими сторонами проложены различные маршруты, проходящие через разные слои доступа к хранилищу[7]. Некоторые из этих маршрутов используют компьютерные сети и сетевые сервера, чтобы достичь хранилища, в то время как другие маршруты в сети не нуждаются и ведут к хранилищу напрямую.


[7] Repository Access (RA) layers

Пред. Уровень выше След.
Возможности Subversion Содержание Установка Subversion


Authentication


With CVS's pserver, you are required to «login» to the server before any read or write operation—you even have to login for anonymous operations. With a Subversion repository using Apache httpd or svnserve as the server, you don't provide any authentication credentials at the outset—if an operation that you perform requires authentication, the server will challenge you for your credentials (whether those credentials are username and password, a client certificate, or even both). So if your repository is world-readable, you will not be required to authenticate at all for read operations.

As with CVS, Subversion still caches your credentials on disk (in your ~/.subversion/auth/ directory) unless you tell it not to by using the --no-auth-cache switch.

The exception to this behavior, however, is in the case of accessing an svnserve server over an SSH tunnel, using the svn+ssh:// URL schema. In that case, the ssh program unconditionally demands authentication just to start the tunnel.

Пред. Уровень выше След.
Versioned Modules Содержание Converting a Repository from CVS to Subversion


Automatic Property Setting


Properties are a powerful feature of Subversion, acting as key components of many Subversion features discussed elsewhere in this and other chapters—textual diff and merge support, keyword substitution, newline translation, etc. But to get the full benefit of properties, they must be set on the right files and directories. Unfortunately, that can be a step easily forgotten in the routine of things, especially since failing to set a property doesn't usually result in an obvious error condition (at least compared to, say, failing to add a file to version control). To help your properties get applied to the places that need them, Subversion provides a couple of simple but useful features.

Whenever you introduce a file to version control using the svn add or svn import commands, Subversion runs a very basic heuristic to determine if that file consists of human-readable or non-human-readable content. If the latter is the decision made, Subversion will automatically set the svn:mime-type property on that file to application/octet-stream (the generic «this is a collection of bytes» MIME type). Of course, if Subversion guesses incorrectly, or if you wish to set the svn:mime-type property to something more precise—perhaps image/png or application/x-shockwave-flash—you can always remove or edit that property.

Subversion also provides the auto-props feature, which allows you to create mappings of filename patterns to property names and values. These mappings are made in your runtime configuration area. They again affect adds and imports, and not only can override any default MIME type decision made by Subversion during those operations, they can also set additional Subversion or custom properties, too. For example, you might create a mapping that says that any time you add JPEG files—ones that match the pattern *.jpg—Subversion should automatically set the svn:mime-type property on those files to image/jpeg. Or perhaps any files that match *.cpp should have svn:eol-style set to native, and svn:keywords set to Id. Auto-prop support is perhaps the handiest property related tool in the Subversion toolbox. See «Config» for more about configuring that support.


[36] Если вы знакомы с XML, то синтаксис XML "Name" использует практически тот же ASCII набор.

[37] Исправление в лог сообщениях орфографических, грамматических ошибок, «просто ошибочных» записей, наверно, самые распространенные случаи использования параметра --revprop.

[38] Для определения исполняемых файлов, файловая система Windows использует расширения файлов (такие, как .EXE, .BAT и .COM).

[39] The patterns are strictly for that directory—they do not carry recursively into subdirectories.

[40] Isn't that the whole point of a build system?

[41] … or maybe even a section of a book …

Пред. Уровень выше След.
Глава 7. Профессиональное использование Subversion Содержание Locking


Become Familiar with Community Policies


Now that you have a working copy containing the latest Subversion source code, you will most certainly want to take a cruise through the «Hacker's Guide to Subversion», which is available either as the www/hacking.html file in the working copy, or on the Subversion website at http://subversion.tigris.org/hacking.html. This guide contains general instructions for contributing to Subversion, including how to properly format your source code for consistency with the rest of the codebase, how to describe your proposed changes with an effective change log message, how to test your changes, and so on. Commit privileges on the Subversion source repository are earned—a government by meritocracy. [52] The «Hacker's Guide» is an invaluable resource when it comes to making sure that your proposed changes earn the praises they deserve without being rejected on technicalities.



Binary Files and Translation


In the most general sense, Subversion handles binary files more gracefully than CVS does. Because CVS uses RCS, it can only store successive full copies of a changing binary file. Subversion, however, expresses differences between files using a binary-differencing algorithm, regardless of whether they contain textual or binary data. That means that all files are stored differentially (compressed) in the repository.

CVS users have to mark binary files with -kb flags, to prevent data from being garbled (due to keyword expansion and line-ending translations). They sometimes forget to do this.

Subversion takes the more paranoid route—first, it never performs any kind of keyword or line-ending translation unless you explicitly ask it do so (see «svn:keywords» and «svn:eol-style» for more details). By default, Subversion treats all file data as literal byte strings, and files are always stored in the repository in an untranslated state.

Second, Subversion maintains an internal notion of whether a file is «text» or «binary» data, but this notion is only extant in the working copy. During an svn update, Subversion will perform contextual merges on locally modified text files, but will not attempt to do so for binary files.

To determine whether a contextual merge is possible, Subversion examines the svn:mime-type property. If the file has no svn:mime-type property, or has a mime-type that is textual (e.g. text/*), Subversion assumes it is text. Otherwise, Subversion assumes the file is binary. Subversion also helps users by running a binary-detection algorithm in the svn import and svn add commands. These commands will make a good guess and then (possibly) set a binary svn:mime-type property on the file being added. (If Subversion guesses wrong, the user can always remove or hand-edit the property.)

Пред. Уровень выше След.
Conflict Resolution Содержание Versioned Modules


Благодарности


This book would not be possible (nor very useful) if Subversion did not exist. For that, the authors would like to thank Brian Behlendorf and CollabNet for the vision to fund such a risky and ambitious new Open Source project; Jim Blandy for the original Subversion name and design—we love you, Jim; Karl Fogel for being such a good friend and a great community leader, in that order.[3]

Thanks to O'Reilly and our editors, Linda Mui and Tatiana Diaz for their patience and support.

Finally, we thank the countless people who contributed to this book with informal reviews, suggestions, and fixes: While this is undoubtedly not a complete list, this book would be incomplete and incorrect without the help of: Jani Averbach, Ryan Barrett, Francois Beausoleil, Jennifer Bevan, Matt Blais, Zack Brown, Martin Buchholz, Brane Cibej, John R. Daily, Peter Davis, Olivier Davy, Robert P. J. Day, Mo DeJong, Brian Denny, Joe Drew, Nick Duffek, Ben Elliston, Justin Erenkrantz, Shlomi Fish, Julian Foad, Chris Foote, Martin Furter, Dave Gilbert, Eric Gillespie, Matthew Gregan, Art Haas, Greg Hudson, Alexis Huxley, Jens B. Jorgensen, Tez Kamihira, David Kimdon, Mark Benedetto King, Andreas J. Koenig, Nuutti Kotivuori, Matt Kraai, Scott Lamb, Vincent Lefevre, Morten Ludvigsen, Paul Lussier, Bruce A. Mah, Philip Martin, Feliciano Matias, Patrick Mayweg, Gareth McCaughan, Jon Middleton, Tim Moloney, Mats Nilsson, Joe Orton, Amy Lyn Pilato, Kevin Pilch-Bisson, Dmitriy Popkov, Michael Price, Mark Proctor, Steffen Prohaska, Daniel Rall, Tobias Ringstrom, Garrett Rooney, Joel Rosdahl, Christian Sauer, Larry Shatzer, Russell Steicke, Sander Striker, Erik Sjoelund, Johan Sundstroem, John Szakmeister, Mason Thomas, Eric Wadsworth, Colin Watson, Alex Waugh, Chad Whitacre, Josef Wolf, Blair Zajac, and the entire Subversion community.



Branches and Tags


Subversion doesn't distinguish between filesystem space and «branch» space; branches and tags are ordinary directories within the filesystem. This is probably the single biggest mental hurdle a CVS user will need to climb. Read all about it in Глава 4, Ветвление и слияние.



Breaking and stealing locks


A repository lock isn't sacred; it can be released not only by the person who created it, but by anyone at all. When somebody other than the original lock creator destroys a lock, we refer to this as breaking the lock.

From the administrator's chair, it's simple to break locks. The svnlook and svnadmin programs have the ability to display and remove locks directly from the repository. (For more information about these tools, see «An Administrator's Toolkit».)

$ svnadmin lslocks /usr/local/svn/repos Path: /project2/images/banana.jpg UUID Token: opaquelocktoken:c32b4d88-e8fb-2310-abb3-153ff1236923 Owner: frank Created: 2005-06-15 13:29:18 -0500 (Wed, 15 Jun 2005) Expires: Comment (1 line): Still improving the yellow color. Path: /project/raisin.jpg UUID Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b Owner: harry Created: 2005-02-16 13:29:18 -0500 (Wed, 16 Feb 2005) Expires: Comment (1 line): Need to make a quick tweak to this image. $ svnadmin rmlocks /usr/local/svn/repos /project/raisin.jpg Removed lock on '/project/raisin.jpg'.

The more interesting option is allowing users to break each other's locks over the network. To do this, one simply needs to pass the --force to the unlock command:

$ whoami sally $ svn status --show-updates M 23 bar.c M O 32 raisin.jpg * 72 foo.h Status against revision: 105 $ svn unlock raisin.jpg svn: 'raisin.jpg' is not locked in this working copy $ svn info raisin.jpg | grep URL URL: http://svn.example.com/repos/project/raisin.jpg $ svn unlock http://svn.example.com/repos/project/raisin.jpg svn: Unlock request failed: 403 Forbidden (http://svn.example.com) $ svn unlock --force http://svn.example.com/repos/project/raisin.jpg 'raisin.jpg' unlocked.

Sally's initial attempt to unlock failed because she ran svn unlock directly on her working copy of the file, and no lock token was present. To remove the lock directly from the repository, she needs to pass a URL to svn unlock. Her first attempt to unlock the URL fails, because she can't authenticate as the lock owner (nor does she have the lock token). But when she passes --force, the authentication and authorization requirements are ignored, and the remote lock is broken.

Of course, simply breaking a lock may not be enough. In the running example, Sally may not only want to break Harry's long-forgotten lock, but re-lock the file for her own use. She can accomplish this by running svn unlock --force and then svn lock back-to-back, but there's a small chance that somebody else might lock the file between the two commands. The simpler thing to is steal the lock, which involves breaking and re-locking the file all in one atomic step. To do this, pass the --force option to svn lock:

$ svn lock raisin.jpg svn: Lock request failed: 423 Locked (http://svn.example.com) $ svn lock --force raisin.jpg 'raisin.jpg' locked by user 'sally'.

In any case, whether the lock is broken or stolen, Harry may be in for a surprise. Harry's working copy still contains the original lock token, but that lock no longer exists. The lock token is said to be defunct. The lock represented by the lock-token has either been broken (no longer in the repository), or stolen (replaced with a different lock). Either way, Harry can see this by asking svn status to contact the repository:

$ whoami harry $ svn status K raisin.jpg $ svn status --show-updates B 32 raisin.jpg $ svn update B raisin.jpg $ svn status $

If the repository lock was broken, then svn status --show-updates displays a B (Broken) symbol next to the file. If a new lock exists in place of the old one, then a T (sTolen) symbol is shown. Finally, svn update notices any defunct lock tokens and removes them from the working copy.

Locking Policies

Different systems have different notions of how strict a lock should be. Some folks argue that locks must be strictly enforced at all costs, releasable only by the original creator or administrator. They argue that if anyone can break a lock, then chaos breaks loose and the whole point of locking is defeated. The other side argues that locks are first and foremost a communication tool. If users are constantly breaking each others' locks, then it represents a cultural failure within the team and the problem falls outside the scope of software enforcement.

Subversion defaults to the «softer» approach, but still allows administrators to create stricter enforcement policies through the use of hook scripts. In particular, the pre-lock and pre-unlock hooks allow administrators to decide when lock creation and lock releases are allowed to happen. Depending on whether or not a lock already exists, these two hooks can decide whether or not to allow a certain user to break or steal a lock. The post-lock and post-unlock hooks are also available, and can be used to send email after locking actions.

To learn more about repository hooks, see «Hook Scripts».



Быстрый старт


Некоторые испытывают трудности поглощения новой технологии читая приближение «с верху вниз», предлагаемое этой книгой. Этот раздел представляет собой очень короткое введение в Subversion и предназначен для того, что бы помочь изучающим «снизу вверх». Если вы из тех, кто предпочитает учиться на экспериментах то последующая демонстрация поможет вам начать. По ходу дела мы давали ссылки на соответствующие главы книги.

Если вы не совсем знакомы с концепциями контроля версий или моделью «копирование-изменение-слияние», используемой как CVS так и Subversion, перед тем как идти дальше, вам нужно прочитать Глава 2, Основные понятия.



Changes


Working copy if operating on files, Repository if operating on URLs



Nothing




Local disk




Nothing




Repository




Nothing




Nothing




Working Copy, Repository




Nothing




Working copy




Working copy, repository if operating on a URL




Working copy, repository if operating on a URL




Working copy, repository only if operating on a URL




Working copy, repository only if operating on a URL




Working copy, repository only if operating on a URL




Working copy, repository only if operating on a URL




Working copy, repository only if operating on a URL




Working copy




Working copy




Nothing




Working copy




Working Copy, Repository




Working copy



Что такое Subversion?


Subversion — это свободная система управления версиями с открытым исходным кодом. Subversion позволяет управлять файлами и каталогами во времени. Дерево файлов помещается в центральное хранилище, которое похоже на обычный сервер файлов с тем отличием, что оно запоминает каждое изменение, внесённое в файл или каталог. Это позволяет восстановить ранние версии данных, исследовать историю изменений данных. Благодаря этому, многие считают систему управления версиями своеобразной «машиной времени».

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

Некоторые системы управления версиями выступают также в качестве систем управления конфигурацией программного обеспечения (SCM[4]). Такие системы специально созданы для управления деревьями исходного кода и обладают множеством особенностей, непосредственно относящихся к разработке программного обеспечения: они понимают языки программирования и предоставляют инструменты для сборки программ. Subversion не является такой системой, она представляет собой систему общего назначения, которую можно использовать для управления любым набором файлов. Ваши файлы могут быть исходным кодом, а для кого-то это будет что-то иное, например списки покупок в продовольственном магазине или сведённые цифровые видеоролики.


[4] Software Configuration Management

Пред.   След.
Благодарности Содержание История Subversion


Что такое ветка?


Предположим, что ваша работа заключается в сопровождении документа, например какого-то руководства, для подразделений в вашей компании. Однажды различные подразделения запросят у вас одно и тоже руководство, но с несколькими частями которые будут немного «подредактированны», так как задачи у них немного различаются.

Как вы поступите в такой ситуации? Вы делаете очевидную вещь: создаете вторую копию документа и начинаете сопровождать две отдельных копии. Когда какое-то из подразделений просит вас внести небольшие изменения, вы включаете их или в одну копию или в другую.

Как правило, вам будет нужно вносить изменения в обе копии. Например, если вы обнаружили опечатку в одной копии, скорее всего, эта же опечатка присутствует и во второй копии. Два документа в общем то одинаковые; отличаются они незначительно в отдельных, специфичных моментах.

В этом заключается основная идея ветки — а именно, направления разработки, которое существует независимо от другого направления, однако имеющие с ним общую историю, если заглянуть немного в прошлое. Ветка всегда берет начало как копия чего-либо и двигается от этого момента создавая свою собственную историю (см. Рисунок 4.1, «Ветки разработки»).

Рисунок 4.1. Ветки разработки

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

Пред.   След.
Подводя итоги Содержание Использование веток


Client Layer


On the client side, the Subversion working copy is where all the action takes place. The bulk of functionality implemented by the client-side libraries exists for the sole purpose of managing working copies—directories full of files and other subdirectories which serve as a sort of local, editable «reflection» of one or more repository locations—and propagating changes to and from the Repository Access layer.

Subversion's working copy library, libsvn_wc, is directly responsible for managing the data in the working copies. To accomplish this, the library stores administrative information about each working copy directory within a special subdirectory. This subdirectory, named .svn, is present in each working copy directory and contains various other files and directories which record state and provide a private workspace for administrative action. For those familiar with CVS, this .svn subdirectory is similar in purpose to the CVS administrative directories found in CVS working copies. For more information about the .svn administrative area, see «Inside the Working Copy Administration Area»in this chapter.

The Subversion client library, libsvn_client, has the broadest responsibility; its job is to mingle the functionality of the working copy library with that of the Repository Access Layer, and then to provide the highest-level API to any application that wishes to perform general revision control actions. For example, the function svn_client_checkout() takes a URL as an argument. It passes this URL to the RA layer and opens an authenticated session with a particular repository. It then asks the repository for a certain tree, and sends this tree into the working copy library, which then writes a full working copy to disk (.svn directories and all).

The client library is designed to be used by any application. While the Subversion source code includes a standard command-line client, it should be very easy to write any number of GUI clients on top of the client library. New GUIs (or any new client, really) for Subversion need not be clunky wrappers around the included command-line client—they have full access via the libsvn_client API to same functionality, data, and callback mechanisms that the command-line client uses.

Binding Directly—A Word About Correctness

Why should your GUI program bind directly with a libsvn_client instead of acting as a wrapper around a command-line program? Besides simply being more efficient, this can address potential correctness issues as well. A command-line program (like the one supplied with Subversion) that binds to the client library needs to effectively translate feedback and requested data bits from C types to some form of human-readable output. This type of translation can be lossy. That is, the program may not display all of the information harvested from the API, or may combine bits of information for compact representation.

If you wrap such a command-line program with yet another program, the second program has access only to already-interpreted (and as we mentioned, likely incomplete) information, which it must again translate into its representation format. With each layer of wrapping, the integrity of the original data is potentially tainted more and more, much like the result of making a copy of a copy (of a copy …) of a favorite audio or video cassette.


[47] We understand that this may come as a shock to sci-fi fans who have long been under the impression that Time was actually the fourth dimension, and we apologize for any emotional trauma induced by our assertion of a different theory.

Пред.   След.
Subversion Repository URLs Содержание Using the APIs


Config


Остальные доступные параметры времени выполнения Subversion, не относящиеся к сетевой работе, находятся в файле config. В данный момент существует всего несколько параметров, но они тоже сгруппированы в разделы, в расчете на их увеличение в будущем.

Раздел auth содержит параметры, относящиеся к аутентификации и авторизации в хранилище. Он содержит:

store-passwords

Устанавливает, используется или не используется кеширование паролей, введенных пользователем в ответ на запрос при аутентификации на сервере. Значением по умолчанию является да. Для запрета кеширования паролей на диск установите этот параметр в нет. Для отдельного запуска svn этот параметр можно переопределить, используя параметр командной строки --no-auth-cache (для тех команд, которые его поддерживают). За более подробной информацией обратитесь к разделу «Кеширование клиентской идентификационной информации».

store-auth-creds

Этот параметр такой же как и store-passwords, за исключением того, что он разрешает или запрещает дисковое кеширование всей информации для аутентификации: имен пользователей, паролей, серверных сертификатов и всей другой кешируемой информации.

Раздел helpers определяет, какие внешние приложения, при выполнении своих задач, будет использовать Subversion. Доступные параметры:

editor-cmd

Определяет программу, которую будет использовать Subversion для ввода лог сообщений, в тех случаях, когда svn commit используется без параметров --message (-m) или --file (-F). Эта же программа используется с командой svn propedit — вызывается временный файл, содержащий текущее значение редактируемого пользователем свойства и редактирование выполняется прямо в программе-редакторе (см. «Свойства»). По умолчанию значение этого свойства не установлено. Если этот параметр не задан, для определения редактора Subversion возвращается к проверке переменных среды SVN_EDITOR, VISUAL и EDITOR (именно в такой последовательности).

diff-cmd

Здесь указывается абсолютный путь к программе определения отличий, используемой, Subversion для «diff»-вывода (такого как при использовании команды svn diff). По умолчанию для определения отличий Subversion использует внутреннюю библиотеку — установка этого параметра заставит ее использовать внешнюю программу. Подробнее об использовании таких программ читайте в разделе «Using External Differencing Tools».

diff3-cmd

Здесь указывается абсолютный путь к программе трехстороннего сравнения. Subversion использует эту программу при объединении изменений, сделанных пользователем, с теми, которые были получены из хранилища. По умолчанию для определения отличий Subversion использует внутреннюю библиотеку — установка этого параметра заставит ее использовать внешнюю программу. Подробнее об использовании таких программ читайте в разделе «Using External Differencing Tools».

diff3-has-program-arg

Этот флаг должен быть установлен в true если программа, указанная в параметре diff3-cmd использует параметр командной строки --diff-program.

Раздел tunnels позволяет определить новые схемы туннелирования при использовании svnserve и клиентских подключений через svn://. За более подробной информацией обращайтесь в раздел «SSH authentication and authorization».

Все что не попало в другие разделы собирается в разделе miscellany[35]. В этом разделе можно найти:

global-ignores

Про выполнении команды svn status, Subversion перечисляет не версионированные файлы и директории вместе с версионированными, отмечая их символом ? (см. «svn status»). Просмотр не интересных, не версионированных элементов при просмотре может раздражать — например объектные файлы, полученные в результате компиляции программы. Параметр global-ignores является перечислением разделннных пробелом обобщений, представляющих имена файлов и директорий которые Subversion не должна показывать, если они не версионированны. Значением, присвоенным по умолчанию, является *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store.

Также как и svn status, команды svn add и svn import тоже игнорируют файлы, подходящие к этому списку. Можно переопределить этот параметр, используя флаг командной строки --no-ignore. Подробнее о более точном контроле игнорирования см. «svn:ignore».

enable-auto-props

Определяет автоматическую установку свойств для вновь добавляемых или импортированных файлов. Значением по умолчанию является no, поэтому для разрешения авто-свойств установите yes. Раздел auto-props этого файла определяет, какие свойства и для каких файлов должны устанавливаться.

log-encoding

Эта переменная задает набор символов кодировки для лог-сообщений фиксаций. Это перманентная форма параметра --encoding (см. «Параметры svn»). Хранилище Subversion хранит лог-сообщения в UTF8, и предполагает, что ваше лог-сообщение написано используя родную локаль операционной ситемы. Кодировку необходимо указывать, если используется любая другая кодировка.

use-commit-times

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

С другой стороны, иногда бывает выгодно, что бы рабочие файлы имели метки времени отражающие время их последнего изменения в хранилище. Команда svn export всегда устанавливает «метку времени последней фиксации» для создаваемого ею дерева файлов. При установке значения этой переменной в yes команды svn checkout, svn update, svn switch и svn revert для используемых ими файлов, так же будут устанавливать метку времени последней фиксации.

Раздел auto-props определяет возможность Subversion-клиента автоматически устанавливать свойства файлов, когда они добавлялись или импортировались. Он содержит любое количество пар ключ-значение, в формате PATTERN = PROPNAME=PROPVALUE, где PATTERN является файловым шаблоном, соответствующих набору имен файлов, а остальная часть строки является свойством и его значением. Множественные совпадения для одного файла приведут к множественной установке свойств для этого файла; однако не гарантируется, что порядок установки авто-свойств будет таким же в каком они указаны в файле конфигурации, поэтому нельзя будет одним правилом «перекрыть» другое. Несколько примеров использования авто-свойств можно найти в файле config. Наконец, если хотите использовать авто-свойства, не забудьте в разделе miscellany установить enable-auto-props в yes.


[34] Переменная среды окружения APPDATA указывает на папку Application Data поэтому к этой директории можно всегда обращаться как к %APPDATA%\Subversion.

[35] Anyone for potluck dinner?

Пред.   След.
Supporting Multiple Repository Access Methods Содержание Свойства


Conflict Resolution


CVS marks conflicts with in-line «conflict markers», and prints a C during an update. Historically, this has caused problems, because CVS isn't doing enough. Many users forget about (or don't see) the C after it whizzes by on their terminal. They often forget that the conflict-markers are even present, and then accidentally commit files containing conflict-markers.

Subversion solves this problem by making conflicts more tangible. It remembers that a file is in a state of conflict, and won't allow you to commit your changes until you run svn resolved. See «Решение конфликтов (при объединении с чужими изменениями)» for more details.

Пред. Уровень выше След.
Metadata Properties Содержание Binary Files and Translation


Contributing to Subversion


The official source of information about the Subversion project is, of course, the project's website at http://subversion.tigris.org/. There you can find information about getting access to the source code and participating on the discussion lists. The Subversion community always welcomes new members. If you are interested in participating in this community by contributing changes to the source code, here are some hints on how to get started.



Converting a Repository from CVS to Subversion


Perhaps the most important way to familiarize CVS users with Subversion is to let them continue to work on their projects using the new system. And while that can be somewhat accomplished using a flat import into a Subversion repository of an exported CVS repository, the more thorough solution involves transferring not just the latest snapshot of their data, but all the history behind it as well, from one system to another. This is an extremely difficult problem to solve that involves deducing changesets in the absence of atomicity, and translating between the systems' completely orthogonal branching policies, among other complications. Still, there are a handful of tools claiming to at least partially support the ability to convert existing CVS repositories into Subversion ones.

One such tool is cvs2svn (http://cvs2svn.tigris.org/), a Python script originally created by members of Subversion's own development community. Others include Lev Serebryakov's RefineCVS (http://lev.serebryakov.spb.ru/refinecvs/). These tools have various levels of completeness, and may make entirely different decisions about how to handle your CVS repository history. Whichever tool you decide to use, be sure to perform as much verification as you can stand on the conversion results—after all, you've worked hard to build that history!

For an updated collection of links to known converter tools, visit the Links page of the Subversion website (http://subversion.tigris.org/project_links.html).

Пред. Уровень выше След.
Authentication Содержание Приложение B. WebDAV и автоматическое управление версиями


Creating locks


In the Subversion repository, a lock is a piece of metadata which grants exclusive access to one user to change a file. This user is said to be the lock owner. Each lock also has a unique identifier, typically a long string of characters, known as the lock token. The repository manages locks in a separate table, and enforces locks during a commit operation. If any commit transaction attempts to modify or delete the file (or delete a parent of the file), the repository will demand two pieces of information:

User authentication. The client performing the commit must be authenticated as the lock owner.

Software authorization. The user's working copy must send the lock token with the commit, proving that it knows exactly which lock it's using.

An example is in order, to demonstrate. Let's say that Harry has decided to change a JPEG image. To prevent other people from committing changes to the file, he locks the file in the repository using the svn lock command:

$ svn lock banana.jpg --message "Editing file for tomorrow's release." 'banana.jpg' locked by user 'harry'. $ svn status K banana.jpg $ svn info banana.jpg Path: banana.jpg Name: banana.jpg URL: http://svn.example.com/repos/project/banana.jpg Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec Revision: 2198 Node Kind: file Schedule: normal Last Changed Author: frank Last Changed Rev: 1950 Last Changed Date: 2005-03-15 12:43:04 -0600 (Tue, 15 Mar 2005) Text Last Updated: 2005-06-08 19:23:07 -0500 (Wed, 08 Jun 2005) Properties Last Updated: 2005-06-08 19:23:07 -0500 (Wed, 08 Jun 2005) Checksum: 3b110d3b10638f5d1f4fe0f436a5a2a5 Lock Token: opaquelocktoken:0c0f600b-88f9-0310-9e48-355b44d4a58e Lock Owner: harry Lock Created: 2005-06-14 17:20:31 -0500 (Tue, 14 Jun 2005) Lock Comment (1 line): Editing file for tomorrow's release.

There are a number of new things demonstrated in the previous example. First, notice that Harry passed the --message option to svn lock. Similar to svn commit, the svn lock command can take comments (either via --message (-m) or --file (-F)) to describe the reason for locking the file. Unlike svn commit, however, svn lock will not demand a message by launching your preferred text editor. Lock comments are optional, but still recommended to aid communication.

Second, the lock attempt succeeded. This means that the file wasn't already locked, and that Harry had the latest version of the file. If Harry's working copy of the file had been out-of-date, the repository would have rejected the request, forcing harry to svn update and reattempt the locking command.

Also notice that after creating the lock in the repository, the working copy has cached information about the lock—most importantly, the lock token. The presence of the lock token is critical. It gives the working copy authorization to make use of the lock later on. The svn status command shows a K next to the file (short for locKed), indicating that the lock token is present.

Regarding lock tokens

A lock token isn't an authentication token, so much as an authorization token. The token isn't a protected secret. In fact, a lock's unique token is discoverable by anyone who runs svn info URL.

A lock token is special only when it lives inside a working copy. It's proof that the lock was created in that particular working copy, and not somewhere else by some other client. Merely authenticating as the lock owner isn't enough to prevent accidents.

For example: suppose you lock a file using a computer at your office, perhaps as part of a changeset in progress. It should not be possible for a working copy (or alternate Subversion client) on your home computer to accidentally commit a change to that same file, just because you've authenticated as the lock's owner. In other words, the lock token prevents one piece of Subversion-related software from undermining the work of another. (In our example, if you really need to change the file from an alternate working copy, you would need to break the lock and re-lock the file.)

Now that Harry has locked banana.jpg, Sally is unable to change or delete that file:

$ whoami sally $ svn delete banana.jpg D banana.jpg $ svn commit -m "Delete useless file." Deleting banana.jpg svn: Commit failed (details follow): svn: DELETE of '/repos/project/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/banana.jpg': 423 Locked (http://svn.example.com)

But Harry, after touching up the banana's shade of yellow, is able to commit his changes to the file. That's because he authenticates as the lock owner, and also because his working copy holds the correct lock token:

$ whoami harry $ svn status M K banana.jpg $ svn commit -m "Make banana more yellow" Sending banana.jpg Transmitting file data . Committed revision 2201. $ svn status $

Notice that after the commit is finished, svn status shows that the lock token is no longer present in working copy. This is the standard behavior of svn commit: it walks the working copy (or list of targets, if you provide such a list), and sends all lock tokens it encounters to the server as part of the commit transaction. After the commit completes successfully, all of the repository locks that were mentioned are released—even on files that weren't committed. The rationale here is to discourage users from being sloppy about locking, or from holding locks for too long. For example, suppose Harry were to haphazardly lock thirty files in a directory named images, because he's unsure of which files he needs to change. He ends up making changes to only four files. When he runs svn commit images, the process would still release all thirty locks.

This behavior of automatically releasing locks can be overridden with the --no-unlock option to svn commit. This is best used for those times when you want to commit changes, but still plan to make more changes and thus need to retain existing locks. This behavior is also semi-permanently tweakable, by setting no-unlock = yes in your run-time config file (see «Параметры времени выполнения».)

Of course, locking a file doesn't oblige one to commit a change to it. The lock can be released at any time with a simple svn unlock command:

$ svn unlock banana.c 'banana.c' unlocked.

Description


This section briefly describes each of the Subversion Apache configuration directives. For an in-depth description of configuring Apache with Subversion, see «httpd, the Apache HTTP server».)



Items specified by PATH are scheduled for deletion upon the next commit. Files (and directories that have not been committed) are immediately removed from the working copy. The command will not remove any unversioned or modified items; use the --force switch to override this behavior.

Items specified by URL are deleted from the repository via an immediate commit. Multiple URLs are committed atomically.




Display the differences between two paths. The three different ways you can use svn diff are:

svn diff [-r N[:M]] [--old OLD-TGT] [--new NEW-TGT] [PATH...] displays the differences between OLD-TGT and NEW-TGT. If PATHs are given, they are treated as relative to OLD-TGT and NEW-TGT and the output is restricted to differences in only those paths. OLD-TGT and NEW-TGT may be working copy paths or URL[@REV]. OLD-TGT defaults to the current working directory and NEW-TGT defaults to OLD-TGT. N defaults to BASE or, if OLD-TGT is a URL, to HEAD. M defaults to the current working version or, if NEW-TGT is a URL, to HEAD. svn diff -r N sets the revision of OLD-TGT to N, svn diff -r N:M also sets the revision of NEW-TGT to M.

svn diff -r N:M URL is shorthand for svn diff -r N:M --old=URL --new=URL.

svn diff [-r N[:M]] URL1[@N] URL2[@M] is shorthand for svn diff [-r N[:M]] --old=URL1 --new=URL2.

If TARGET is a URL, then revs N and M can be given either via the --revision or by using «@» notation as described earlier.

If TARGET is a working copy path, then the --revision switch means:

--revision N:M

The server compares TARGET@N and TARGET@M.

--revision N

The client compares TARGET@N against working copy.

(no --revision)

The client compares base and working copies of TARGET.

If the alternate syntax is used, the server compares URL1 and URL2 at revisions N and M respectively. If either N or M are omitted, a value of HEAD is assumed.

By default, svn diff ignores the ancestry of files and merely compares the contents of the two files being compared. If you use --notice-ancestry, the ancestry of the paths in question will be taken into consideration when comparing revisions (that is, if you run svn diff on two files with identical contents but different ancestry you will see the entire contents of the file as having been removed and added again).




The first form exports a clean directory tree from the repository specified by URL, at revision REV if it is given, otherwise at HEAD, into PATH. If PATH is omitted, the last component of the URL is used for the local directory name.

The second form exports a clean directory tree from the working copy specified by PATH1 into PATH2. All local changes will be preserved, but files not under version control will not be copied.




This is your best friend when you're using Subversion and this book isn't within reach!




Recursively commit a copy of PATH to URL. If PATH is omitted «.» is assumed. Parent directories are created in the repository as necessary.




Print information about both working copy paths and URLs, including:

Path

Name

URL

Revision

Repository Root

Repository UUID

Node Kind

Last Changed Author

Last Changed Revision

Last Changed Date

Text Last Updated

Properties Last Updated

Checksum

Lock Token

Lock Owner

Lock Creation Date




List each TARGET file and the contents of each TARGET directory as they exist in the repository. If TARGET is a working copy path, the corresponding repository URL will be used.

The default TARGET is «.», meaning the repository URL of the current working copy directory.

With --verbose, the following fields show the status of the item:

Revision number of the last commit

Author of the last commit

Size (in bytes)

Date and time of the last commit

With --xml, output is in XML format (with a header and an enclosing document element unless --incremental is also specified). All of the information is present; the --verbose option is not accepted.




Lock each TARGET. If any TARGET is already locked by another user, print a warning and continue locking the rest of the TARGETs. Use --force to steal a lock from another user or working copy.




The default target is the path of your current directory. If no arguments are supplied, svn log shows the log messages for all files and directories inside of (and including) the current working directory of your working copy. You can refine the results by specifying a path, one or more revisions, or any combination of the two. The default revision range for a local path is BASE:1.

If you specify a URL alone, then it prints log messages for everything that the URL contains. If you add paths past the URL, only messages for those paths under that URL will be printed. The default revision range for a URL is HEAD:1.

With --verbose, svn log will also print all affected paths with each log message. With --quiet, svn log will not print the log message body itself (this is compatible with --verbose).

Each log message is printed just once, even if more than one of the affected paths for that revision were explicitly requested. Logs follow copy history by default. Use --stop-on-copy to disable this behavior, which can be useful for determining branch points.




In the first and second forms, the source paths (URLs in the first form, working copy paths in the second) are specified at revisions N and M. These are the two sources to be compared. The revisions default to HEAD if omitted.

In the third form, SOURCE can be a URL or working copy item, in which case the corresponding URL is used. This URL, at revisions N and M, defines the two sources to be compared.

WCPATH is the working copy path that will receive the changes. If WCPATH is omitted, a default value of «.» is assumed, unless the sources have identical basenames that match a file within «.»: in which case, the differences will be applied to that file.

Unlike svn diff, the merge command takes the ancestry of a file into consideration when performing a merge operation. This is very important when you're merging changes from one branch into another and you've renamed a file on one branch but not the other.




Create a directory with a name given by the final component of the PATH or URL. A directory specified by a working copy PATH is scheduled for addition in the working copy. A directory specified by a URL is created in the repository via an immediate commit. Multiple directory URLs are committed atomically. In both cases all the intermediate directories must already exist.




This command moves a file or directory in your working copy or in the repository.




This removes properties from files, directories, or revisions. The first form removes versioned properties in your working copy, while the second removes unversioned remote properties on a repository revision.




Edit one or more properties using your favorite editor. The first form edits versioned properties in your working copy, while the second edits unversioned remote properties on a repository revision.




Print the value of a property on files, directories, or revisions. The first form prints the versioned property of an item or items in your working copy, while the second prints unversioned remote property on a repository revision. See «Свойства» for more information on properties.




List all properties on files, directories, or revisions. The first form lists versioned properties in your working copy, while the second lists unversioned remote properties on a repository revision.




Set PROPNAME to PROPVAL on files, directories, or revisions. The first example creates a versioned, local property change in the working copy, and the second creates an unversioned, remote property change on a repository revision.




Remove «conflicted» state on working copy files or directories. This routine does not semantically resolve conflict markers; it merely removes conflict-related artifact files and allows PATH to be committed again; that is, it tells Subversion that the conflicts have been «resolved». See «Решение конфликтов (при объединении с чужими изменениями)» for an in-depth look at resolving conflicts.




Reverts any local changes to a file or directory and resolves any conflicted states. svn revert will not only revert the contents of an item in your working copy, but also any property changes. Finally, you can use it to undo any scheduling operations that you may have done (e.g. files scheduled for addition or deletion can be «unscheduled»).




Print the status of working copy files and directories. With no arguments, it prints only locally modified items (no repository access). With --show-updates, add working revision and server out-of-date information. With --verbose, print full revision information on every item.

The first six columns in the output are each one character wide, and each column gives you information about different aspects of each working copy item.

The first column indicates that an item was added, deleted, or otherwise changed.

' '

No modifications.

'A'

Item is scheduled for Addition.

'D'

Item is scheduled for Deletion.

'M'

Item has been modified.

'R'

Item has been replaced in your working copy.

'C'

The contents (as opposed to the properties) of the item conflict with updates received from the repository.

'X'

Item is related to an externals definition.

'I'

Item is being ignored (e.g. with the svn:ignore property).

'?'

Item is not under version control.

'!'

Item is missing (e.g. you moved or deleted it without using svn). This also indicates that a directory is incomplete (a checkout or update was interrupted).

'~'

Item is versioned as one kind of object (file, directory, link), but has been replaced by different kind of object.

The second column tells the status of a file's or directory's properties.

' '

No modifications.

'M'

Properties for this item have been modified.

'C'

Properties for this item are in conflict with property updates received from the repository.

The third column is populated only if the working copy directory is locked.

' '

Item is not locked.

'L'

Item is locked.

The fourth column is populated only if the item is scheduled for addition-with-history.

' '

No history scheduled with commit.

'+'

History scheduled with commit.

The fifth column is populated only if the item is switched relative to its parent (see «Переключение рабочей копии»).

' '

Item is a child of its parent directory.

'S'

Item is switched.

The sixth column is populated with lock information.

' '

When --show-updates is used, the file is not locked. If --show-updates is not used, this merely means that the file is not locked in this working copy.

K

File is locked in this working copy.

O

File is locked either by another user or in another working copy. This only appears when --show-updates is used.

T

File was locked in this working copy, but the lock has been «stolen»and is invalid. The file is currently locked in the repository. This only appears when --show-updates is used.

B

File was locked in this working copy, but the lock has been «broken»and is invalid. The file is no longer locked This only appears when --show-updates is used.

The out-of-date information appears in the seventh column (only if you pass the --show-updates switch).

' '

The item in your working copy is up-to-date.

'*'

A newer revision of the item exists on the server.

The remaining fields are variable width and delimited by spaces. The working revision is the next field if the --show-updates or --verbose switches are passed.

If the --verbose switch is passed, the last committed revision and last committed author are displayed next.

The working copy path is always the final field, so it can include spaces.




This subcommand updates your working copy to mirror a new URL—usually a URL which shares a common ancestor with your working copy, although not necessarily. This is the Subversion way to move a working copy to a new branch. See «Переключение рабочей копии» for an in-depth look at switching.




Unlock each TARGET. If any TARGET is either locked by another user or no valid lock token exists in the working copy, print a warning and continue unlocking the rest of the TARGETs. Use --force to break a lock belonging to another user or working copy.




svn update brings changes from the repository into your working copy. If no revision given, it brings your working copy up-to-date with the HEAD revision. Otherwise, it synchronizes the working copy to the revision given by the --revision switch. As part of the synchronization, svn update also removes any stale locks found in the working copy.

For each updated item a line will start with a character reporting the action taken. These characters have the following meaning:

A

Added

D

Deleted

U

Updated

C

Conflict

G

Merged

A character in the first column signifies an update to the actual file, while updates to the file's properties are shown in the second column.




Create a new, empty repository at the path provided. If the provided directory does not exist, it will be created for you.[55] As of Subversion 1.2, svnadmin creates new repositories with the fsfs filesystem backend by default.




svnadmin deltify only exists in 1.0.x due to historical reasons. This command is deprecated and no longer needed.

It dates from a time when Subversion offered administrators greater control over compression strategies in the repository. This turned out to be a lot of complexity for very little gain, and this «feature» was deprecated.




Dump the contents of filesystem to stdout in a «dumpfile» portable format, sending feedback to stderr. Dump revisions LOWER rev through UPPER rev. If no revisions are given, dump all revision trees. If only LOWER is given, dump that one revision tree. See «Migrating a Repository» for a practical use.

By default, the Subversion dumpfile stream contains a single revision (the first revision in the requested revision range) in which every file and directory in the repository in that revision is presented as if that whole tree was added at once, followed by other revisions (the remainder of the revisions in the requested range) which contain only the files and directories which were modified in those revisions. For a modified file, the complete fulltext representation of its contents, as well as all of its properties, are presented in the dumpfile; for a directory, all of its properties are presented.

There are a pair of useful options which modify the dumpfile generator's behavior. The first is the --incremental option, which simply causes that first revision in the dumpfile stream to contain only the files and directories modified in that revision, instead of being presented as the addition of a new tree, and in exactly the same way that every other revision in the dumpfile is presented. This is useful for generating a dumpfile that is to be loaded into another repository which already has the files and directories that exist in the original repository.

The second useful option is --deltas. This switch causes svnadmin dump to, instead of emitting fulltext representations of file contents and property lists, emit only deltas of those items against their previous versions. This reduces (in some cases, drastically) the size of the dumpfile that svnadmin dump creates. There are, however, disadvantages to using this option—deltified dumpfiles are more CPU intensive to create, cannot be operated on by svndumpfilter, and tend not to compress as well as their non-deltified counterparts when using third-party tools like gzip and bzip2.




This subcommand is useful when you're trapped on a desert island with neither a net connection nor a copy of this book.




This subcommand makes a full «hot» backup of your repository, including all hooks, configuration files, and, of course, database files. If you pass the --clean-logs switch, svnadmin will perform a hotcopy of your repository, and then remove unused Berkeley DB logs from the original repository. You can run this command at any time and make a safe copy of the repository, regardless of whether other processes are using the repository.




Berkeley DB creates logs of all changes to the repository, which allow it to recover in the face of catastrophe. Unless you enable DB_LOG_AUTOREMOVE, the log files accumulate, although most are no longer used and can be deleted to reclaim disk space. See «Managing Disk Space» for more information.

Пред. Уровень выше След.
svnadmin hotcopy Содержание svnadmin list-unused-dblogs



Berkeley DB creates logs of all changes to the repository, which allow it to recover in the face of catastrophe. Unless you enable DB_LOG_AUTOREMOVE, the log files accumulate, although most are no longer used and can be deleted to reclaim disk space. See «Managing Disk Space» for more information.




Read a «dumpfile»-formatted stream from stdin, committing new revisions into the repository's filesystem. Send progress feedback to stdout.




Print descriptions of all locks in a repository.




Print the names of all uncommitted transactions. See «Repository Cleanup» for information on how uncommitted transactions are created and what you should do with them.




Run this command if you get an error indicating that your repository needs to be recovered.




Remove lock from each LOCKED_PATH.




Delete outstanding transactions from a repository. This is covered in detail in «Repository Cleanup».




Set the log-message on revision REVISION to the contents of FILE.

This is similar to using svn propset --revprop to set the svn:log property on a revision, except that you can also use the option --bypass-hooks to avoid running any pre- or post-commit hooks, which is useful if the modification of revision properties has not been enabled in the pre-revprop-change hook.




Run this command if you wish to verify the integrity of your repository. This basically iterates through all revisions in the repository by internally dumping all revisions and discarding the output.



Directives


DAV svn

This directive must be included in any Directory or Location block for a Subversion repository. It tells httpd to use the Subversion backend for mod_dav to handle all requests.

SVNAutoversioning On

This directive allows write requests from WebDAV clients to result in automatic commits. A generic log message is auto-generated and attached to each revision. If you enable Autoversioning, you'll likely want to set ModMimeUsePathInfo On so that mod_mime can set svn:mime-type to the correct mime-type automatically (as best as mod_mime is able to, of course). For more information, see Приложение B, WebDAV и автоматическое управление версиями

SVNPath

This directive specifies the location in the filesystem for a Subversion repository's files. In a configuration block for a Subversion repository, either this directive or SVNParentPath must be present, but not both.

SVNSpecialURI

Specifies the URI component (namespace) for special Subversion resources. The default is «!svn», and most administrators will never use this directive. Only set this if there is a pressing need to have a file named !svn in your repository. If you change this on a server already in use, it will break all of the outstanding working copies and your users will hunt you down with pitchforks and flaming torches.

SVNReposName

Specifies the name of a Subversion repository for use in HTTP GET requests. This value will be prepended to the title of all directory listings (which are served when you navigate to a Subversion repository with a web browser). This directive is optional.

SVNIndexXSLT

Specifies the URI of an XSL transformation for directory indexes. This directive is optional.

SVNParentPath

Specifies the location in the filesystem of a parent directory whose child directories are Subversion repositories. In a configuration block for a Subversion repository, either this directive or SVNPath must be present, but not both.

SVNPathAuthz

Control path-based authorization by enabling or disabling subrequests. See «Disabling Path-based Checks» for details.

Пред. Уровень выше След.
mod_dav_svn Содержание Приложение A. Subversion для пользователей CVS


Directory Versions


Subversion tracks tree structures, not just file contents. It's one of the biggest reasons Subversion was written to replace CVS.

Here's what this means to you, as a former CVS user:

The svn add and svn delete commands work on directories now, just as they work on files. So do svn copy and svn move. However, these commands do not cause any kind of immediate change in the repository. Instead, the working items are simply «scheduled» for addition or deletion. No repository changes happen until you run svn commit.

Directories aren't dumb containers anymore; they have revision numbers like files. (Or more properly, it's correct to talk about «directory foo/ in revision 5».)

Let's talk more about that last point. Directory versioning is a hard problem; because we want to allow mixed-revision working copies, there are some limitations on how far we can abuse this model.

From a theoretical point of view, we define «revision 5 of directory foo» to mean a specific collection of directory-entries and properties. Now suppose we start adding and removing files from foo, and then commit. It would be a lie to say that we still have revision 5 of foo. However, if we bumped foo's revision number after the commit, that would be a lie too; there may be other changes to foo we haven't yet received, because we haven't updated yet.

Subversion deals with this problem by quietly tracking committed adds and deletes in the .svn area. When you eventually run svn update, all accounts are settled with the repository, and the directory's new revision number is set correctly. Therefore, only after an update is it truly safe to say that you have a «perfect» revision of a directory. Most of the time, your working copy will contain «imperfect» directory revisions.

Similarly, a problem arises if you attempt to commit property changes on a directory. Normally, the commit would bump the working directory's local revision number. But again, that would be a lie, because there may be adds or deletes that the directory doesn't yet have, because no update has happened. Therefore, you are not allowed to commit property-changes on a directory unless the directory is up-to-date.

For more discussion about the limitations of directory versioning, see «Смешивание правок в рабочих копиях».

Пред. Уровень выше След.
Приложение A. Subversion для пользователей CVS Содержание More Disconnected Operations


Discovering locks


When a commit fails due to someone else's locks, it's fairly easy to learn about them. The easiest of these is svn status --show-updates:

$ whoami sally $ svn status --show-updates M 23 bar.c M O 32 raisin.jpg * 72 foo.h Status against revision: 105

In this example, Sally can see not only that her copy of foo.h is out-of-date, but that one of the two modified files she plans to commit is locked in the repository. The O symbol stands for «Other», meaning that a lock exists on the file, and was created by somebody else. If she were to attempt a commit, the lock on raisin.jpg would prevent it. Sally is left wondering who made the lock, when, and why. Once again, svn info has the answers:

$ svn info http://svn.example.com/repos/project/raisin.jpg Path: raisin.jpg Name: raisin.jpg URL: http://svn.example.com/repos/project/raisin.jpg Repository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec Revision: 105 Node Kind: file Last Changed Author: sally Last Changed Rev: 32 Last Changed Date: 2005-01-25 12:43:04 -0600 (Tue, 25 Jan 2005) Lock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b Lock Owner: harry Lock Created: 2005-02-16 13:29:18 -0500 (Wed, 16 Feb 2005) Lock Comment (1 line): Need to make a quick tweak to this image.

Just as svn info can be used to examine objects in the working copy, it can also be used to examine objects in the repository. If the main argument to svn info is a working copy path, then all of the working copy's cached information is displayed; any mention of a lock means that the working copy is holding a lock token (if a file is locked by another user or in another working copy, svn info on a working copy path will show no lock information at all). If the main argument to svn info is a URL, then the information reflects the latest version of an object in the repository; any mention of a lock describes the current lock on the object.

So in this particular example, Sally can see that Harry locked the file on February 16th to «make a quick tweak». It being June, she suspects that he probably forgot all about the lock. She might phone Harry to complain and ask him to release the lock. If he's unavailable, she might try to forcibly break the lock herself or ask an administrator to do so.



Distinction Between Status and Update


In Subversion, we've tried to erase a lot of the confusion between the cvs status and cvs update commands.

The cvs status command has two purposes: first, to show the user any local modifications in the working copy, and second, to show the user which files are out-of-date. Unfortunately, because of CVS's hard-to-read status output, many CVS users don't take advantage of this command at all. Instead, they've developed a habit of running cvs update or cvs -n update to quickly see their changes. If users forget to use the -n option, this has the side effect of merging repository changes they may not be ready to deal with.

With Subversion, we've tried to remove this muddle by making the output of svn status easy to read for both humans and parsers. Also, svn update only prints information about files that are updated, not local modifications.



Для кого написана эта книга?


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

Вместе с тем, программа svn работает и на других платформах, например в Microsoft Windows. Ввод и вывод этой программы в Windows и Unix практически идентичны, за исключением незначительных различий, вроде использования символа обратной косой черты (\) вместо прямой косой (/) в качестве разделителя компонентов пути к файлу. Пользователи Windows могут также работать с приведёнными примерами в среде эмуляции Unix Cygwin, чтобы свести на нет даже самые незначительные различия.

Многие наши читатели — программисты или системные администраторы, испытывающие потребность отслеживать изменения в исходном коде. Такое использование Subversion является самым распространённым и положено в основу всех примеров в этой книге. Однако, Subversion можно использовать для управления информацией самого разного рода: графика, музыка, базы данных, документация — этот список можно продолжать до бесконечности. Для Subversion любые данные — это просто данные.

Мы писали книгу исходя из того, что читатель никогда не использовал управление версиями раньше, но в то же время пытались облегчить переход на Subversion для пользователей CVS. CVS посвящены специальные врезки в тексте книги, а обзор основных различий между CVS и Subversion вынесен в отдельное приложение.


[1] Система параллельного управления версиями

Пред.   След.
Предисловие Содержание Как читать эту книгу?


Donate Your Changes


After making your modifications to the source code, compose a clear and concise log message to describe those changes and the reasons for them. Then, send an email to the developers list containing your log message and the output of svn diff (from the top of your Subversion working copy). If the community members consider your changes acceptable, someone who has commit privileges (permission to make new revisions in the Subversion source repository) will add your changes to the public source code tree. Recall that permission to directly commit changes to the repository is granted on merit—if you demonstrate comprehension of Subversion, programming competency, and a «team spirit», you will likely be awarded that permission.


[51] Note that the URL checked out in the example above ends not with svn, but with a subdirectory thereof called trunk. See our discussion of Subversion's branching and tagging model for the reasoning behind this.

[52] While this may superficially appear as some sort of elitism, this «earn your commit privileges» notion is about efficiency—whether it costs more in time and effort to review and apply someone else's changes that are likely to be safe and useful, versus the potential costs of undoing changes that are dangerous.

[53] You might want to grab some popcorn. «Thorough», in this instance, translates to somewhere in the neighborhood of thirty minutes of non-interactive machine churn.

Пред. Уровень выше След.
Programming with Memory Pools Содержание Глава 9. Полное справочное руководство по Subversion


Example


This shows the beginning of loading a repository from a backup file (made, of course, with svnadmin dump):

$ svnadmin load /usr/local/svn/restored < repos-backup <<< Started new txn, based on original revision 1 * adding path : test ... done. * adding path : test/a ... done. …

Or if you want to load into a subdirectory:

$ svnadmin load --parent-dir new/subdir/for/project /usr/local/svn/restored < repos-backup <<< Started new txn, based on original revision 1 * adding path : test ... done. * adding path : test/a ... done. …
Пред. Уровень выше След.
svnadmin list-unused-dblogs Содержание svnadmin lslocks

This lists the one locked file in the repository at /svn/repos

$ svnadmin lslocks /svn/repos Path: /tree.jpg UUID Token: opaquelocktoken:ab00ddf0-6afb-0310-9cd0-dda813329753 Owner: harry Created: 2005-07-08 17:27:36 -0500 (Fri, 08 Jul 2005) Expires: Comment (1 line): Rework the uppermost branches on the bald cypress in the foreground.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin loadя‘®¤Ґа¦ ­ЁҐяsvnadmin lstxns



This deletes the locks on tree.jpg and house.jpg in the repository at /svn/repos

$ svnadmin rmlocks /svn/repos tree.jpg house.jpg Removed lock on '/tree.jpg. Removed lock on '/house.jpg.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin recoverя‘®¤Ґа¦ ­ЁҐяsvnadmin rmtxns



Examples


Using svn to delete a file from your working copy merely schedules it to be deleted. When you commit, the file is deleted in the repository.

$ svn delete myfile D myfile $ svn commit -m "Deleted file 'myfile'." Deleting myfile Transmitting file data . Committed revision 14.

Deleting a URL, however, is immediate, so you have to supply a log message:

$ svn delete -m "Deleting file 'yourfile'" file:///tmp/repos/test/yourfile Committed revision 15.

Here's an example of how to force deletion of a file that has local mods:

$ svn delete over-there svn: Attempting restricted operation for modified resource svn: Use --force to override this restriction svn: 'over-there' has local modifications $ svn delete --force over-there D over-there
Пред. Уровень выше След.
svn copy Содержание svn diff


Compare BASE and your working copy (one of the most popular uses of svn diff):

$ svn diff COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (revision 4404) +++ COMMITTERS (working copy)

See how your working copy's modifications compare against an older revision:

$ svn diff -r 3900 COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (revision 3900) +++ COMMITTERS (working copy)

Compare revision 3000 to revision 3500 using <@> syntax:

$ svn diff http://svn.collab.net/repos/svn/trunk/COMMITTERS@3000 http://svn.collab.net/repos/svn/trunk/COMMITTERS@3500 Index: COMMITTERS =================================================================== --- COMMITTERS (revision 3000) +++ COMMITTERS (revision 3500) :

Compare revision 3000 to revision 3500 using range notation (you only pass the one URL in this case):

$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk/COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (revision 3000) +++ COMMITTERS (revision 3500)

Compare revision 3000 to revision 3500 of all files in trunk using range notation:

$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk

Compare revision 3000 to revision 3500 of only three files in trunk using range notation:

$ svn diff -r 3000:3500 --old http://svn.collab.net/repos/svn/trunk COMMITTERS README HACKING

If you have a working copy, you can obtain the differences without typing in the long URLs:

$ svn diff -r 3000:3500 COMMITTERS Index: COMMITTERS =================================================================== --- COMMITTERS (revision 3000) +++ COMMITTERS (revision 3500)

Use --diff-cmd CMD -x to pass arguments directly to the external diff program

$ svn diff --diff-cmd /usr/bin/diff -x "-i -b" COMMITTERS Index: COMMITTERS =================================================================== 0a1,2 > This is a test >
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn deleteя‘®¤Ґа¦ ­ЁҐяsvn export



Export from your working copy (doesn't print every file and directory):

$ svn export a-wc my-export Export complete.

Export directly from the repository (prints every file and directory):

$ svn export file:///tmp/repos my-export A my-export/test A my-export/quiz : Exported revision 15.

When rolling operating-system-specific release packages, it can be useful to export a tree which uses a specific EOL character for line endings. The --native-eol option will do this, but it only affects files that have svn:eol-style = native properties attached to them. For example, to export a tree with all CRLF line endings (possibly for a Windows .zip file distribution):

$ svn export file://tmp/repos my-export --native-eol CRLF A my-export/test A my-export/quiz : Exported revision 15.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn diffя‘®¤Ґа¦ ­ЁҐяsvn help



This imports the local directory myproj into the root of your repository:

$ svn import -m "New import" myproj http://svn.red-bean.com/repos/test Adding myproj/sample.txt : Transmitting file data ......... Committed revision 16.

This imports the local directory myproj into trunk/misc in your repository. The directory trunk/misc need not exist before you import into it-svn import will recursively create directories for you:

$ svn import -m "New import" myproj \ http://svn.red-bean.com/repos/test/trunk/misc/myproj Adding myproj/sample.txt : Transmitting file data ......... Committed revision 19.

After importing data, note that the original tree is not under version control. To start working, you still need to svn checkout a fresh working copy of the tree.

ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn helpя‘®¤Ґа¦ ­ЁҐяsvn info



svn info will show you all the useful information that it has for items in your working copy. It will show information for files:

$ svn info foo.c Path: foo.c Name: foo.c URL: http://svn.red-bean.com/repos/test/foo.c Repository Root: http://svn.red-bean.com/repos/test Repository UUID: 5e7d134a-54fb-0310-bd04-b611643e5c25 Revision: 4417 Node Kind: file Schedule: normal Last Changed Author: sally Last Changed Rev: 20 Last Changed Date: 2003-01-13 16:43:13 -0600 (Mon, 13 Jan 2003) Text Last Updated: 2003-01-16 21:18:16 -0600 (Thu, 16 Jan 2003) Properties Last Updated: 2003-01-13 21:50:19 -0600 (Mon, 13 Jan 2003) Checksum: /3L38YwzhT93BWvgpdF6Zw==

It will also show information for directories:

$ svn info vendors Path: vendors URL: http://svn.red-bean.com/repos/test/vendors Repository Root: http://svn.red-bean.com/repos/test Repository UUID: 5e7d134a-54fb-0310-bd04-b611643e5c25 Revision: 19 Node Kind: directory Schedule: normal Last Changed Author: harry Last Changed Rev: 19 Last Changed Date: 2003-01-16 23:21:19 -0600 (Thu, 16 Jan 2003)

svn info also acts on URLs (also note that the file readme.doc in this example is locked, so lock information is also provided):

$ svn info http://svn.red-bean.com/repos/test/readme.doc Path: readme.doc Name: readme.doc URL: http://svn.red-bean.com/repos/test/readme.doc Repository Root: http://svn.red-bean.com/repos/test Repository UUID: 5e7d134a-54fb-0310-bd04-b611643e5c25 Revision: 1 Node Kind: file Schedule: normal Last Changed Author: sally Last Changed Rev: 42 Last Changed Date: 2003-01-14 23:21:19 -0600 (Tue, 14 Jan 2003) Text Last Updated: 2003-01-14 23:21:19 -0600 (Tue, 14 Jan 2003) Checksum: d41d8cd98f00b204e9800998ecf8427e Lock Token: opaquelocktoken:14011d4b-54fb-0310-8541-dbd16bd471b2 Lock Owner: harry Lock Created: 2003-01-15 17:35:12 -0600 (Wed, 15 Jan 2003)
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn importя‘®¤Ґа¦ ­ЁҐяsvn list



svn list is most useful if you want to see what files a repository has without downloading a working copy:

$ svn list http://svn.red-bean.com/repos/test/support README.txt INSTALL examples/ :

You can pass the --verbose switch for additional information, rather like the UNIX command ls -l:

$ svn list --verbose file:///tmp/repos 16 sally 28361 Jan 16 23:18 README.txt 27 sally 0 Jan 18 15:27 INSTALL 24 harry Jan 18 11:27 examples/

For further details, see <svn list>.

ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn infoя‘®¤Ґа¦ ­ЁҐяsvn lock



Lock two files in your working copy:

$ svn lock tree.jpg house.jpg 'tree.jpg' locked by user 'harry'. 'house.jpg' locked by user 'harry'.

Lock a file in your working copy that is currently locked by another user:

$ svn lock tree.jpg svn: warning: Path '/tree.jpg is already locked by user 'harry in \ filesystem '/svn/repos/db' $ svn lock --force foo 'tree.jpg' locked by user 'sally'.

Lock a file without a working copy:

$ svn lock http://svn.red-bean.com/repos/test/tree.jpg 'tree.jpg' locked by user 'sally'.

For further details, see .

ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn listя‘®¤Ґа¦ ­ЁҐяsvn log



You can see the log messages for all the paths that changed in your working copy by running svn log from the top:

$ svn log ------------------------------------------------------------------------ r20 | harry | 2003-01-17 22:56:19 -0600 (Fri, 17 Jan 2003) | 1 line Tweak. ------------------------------------------------------------------------ r17 | sally | 2003-01-16 23:21:19 -0600 (Thu, 16 Jan 2003) | 2 lines :

Examine all log messages for a particular file in your working copy:

$ svn log foo.c ------------------------------------------------------------------------ r32 | sally | 2003-01-13 00:43:13 -0600 (Mon, 13 Jan 2003) | 1 line Added defines. ------------------------------------------------------------------------ r28 | sally | 2003-01-07 21:48:33 -0600 (Tue, 07 Jan 2003) | 3 lines :

If you don't have a working copy handy, you can log a URL:

$ svn log http://svn.red-bean.com/repos/test/foo.c ------------------------------------------------------------------------ r32 | sally | 2003-01-13 00:43:13 -0600 (Mon, 13 Jan 2003) | 1 line Added defines. ------------------------------------------------------------------------ r28 | sally | 2003-01-07 21:48:33 -0600 (Tue, 07 Jan 2003) | 3 lines :

If you want several distinct paths underneath the same URL, you can use the URL [PATH...] syntax.

$ svn log http://svn.red-bean.com/repos/test/ foo.c bar.c ------------------------------------------------------------------------ r32 | sally | 2003-01-13 00:43:13 -0600 (Mon, 13 Jan 2003) | 1 line Added defines. ------------------------------------------------------------------------ r31 | harry | 2003-01-10 12:25:08 -0600 (Fri, 10 Jan 2003) | 1 line Added new file bar.c ------------------------------------------------------------------------ r28 | sally | 2003-01-07 21:48:33 -0600 (Tue, 07 Jan 2003) | 3 lines :

When you're concatenating the results of multiple calls to the log command, you may want to use the --incremental switch. svn log normally prints out a dashed line at the beginning of a log message, after each subsequent log message, and following the final log message. If you ran svn log on a range of two revisions, you would get this:

$ svn log -r 14:15 ------------------------------------------------------------------------ r14 | ... ------------------------------------------------------------------------ r15 | ... ------------------------------------------------------------------------

However, if you wanted to gather 2 non-sequential log messages into a file, you might do something like this:

$ svn log -r 14 > mylog $ svn log -r 19 >> mylog $ svn log -r 27 >> mylog $ cat mylog ------------------------------------------------------------------------ r14 | ... ------------------------------------------------------------------------ ------------------------------------------------------------------------ r19 | ... ------------------------------------------------------------------------ ------------------------------------------------------------------------ r27 | ... ------------------------------------------------------------------------

You can avoid the clutter of the double dashed lines in your output by using the incremental switch:

$ svn log --incremental -r 14 > mylog $ svn log --incremental -r 19 >> mylog $ svn log --incremental -r 27 >> mylog $ cat mylog ------------------------------------------------------------------------ r14 | ... ------------------------------------------------------------------------ r19 | ... ------------------------------------------------------------------------ r27 | ...

The --incremental switch provides similar output control when using the --xml switch.




Merge a branch back into the trunk (assuming that you have a working copy of the trunk, and that the branch was created in revision 250):

$ svn merge -r 250:HEAD http://svn.red-bean.com/repos/branches/my-branch U myproj/tiny.txt U myproj/thhgttg.txt U myproj/win.txt U myproj/flo.txt

If you branched at revision 23, and you want to merge changes on trunk into your branch, you could do this from inside the working copy of your branch:

$ svn merge -r 23:30 file:///tmp/repos/trunk/vendors U myproj/thhgttg.txt :

To merge changes to a single file:

$ cd myproj $ svn merge -r 30:31 thhgttg.txt U thhgttg.txt
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn logя‘®¤Ґа¦ ­ЁҐяsvn mkdir



Create a directory in your working copy:

$ svn mkdir newdir A newdir

Create one in the repository (instant commit, so a log message is required):

$ svn mkdir -m "Making a new dir." http://svn.red-bean.com/repos/newdir Committed revision 26.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn mergeя‘®¤Ґа¦ ­ЁҐяsvn move



Move a file in your working copy:

$ svn move foo.c bar.c A bar.c D foo.c

Move a file in the repository (an immediate commit, so it requires a commit message):

$ svn move -m "Move a file" http://svn.red-bean.com/repos/foo.c \ http://svn.red-bean.com/repos/bar.c Committed revision 27.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn mkdirя‘®¤Ґа¦ ­ЁҐяsvn propdel



Delete a property from a file in your working copy

$ svn propdel svn:mime-type some-script property 'svn:mime-type' deleted from 'some-script'.

Delete a revision property:

$ svn propdel --revprop -r 26 release-date property 'release-date' deleted from repository revision '26'
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn moveя‘®¤Ґа¦ ­ЁҐяsvn propedit



svn propedit makes it easy to modify properties that have multiple values:

$ svn propedit svn:keywords foo.c <svn will launch your favorite editor here, with a buffer open containing the current contents of the svn:keywords property. You can add multiple values to a property easily here by entering one value per line.> Set new value for property 'svn:keywords' on 'foo.c'
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn propdelя‘®¤Ґа¦ ­ЁҐяsvn propget



Examine a property of a file in your working copy:

$ svn propget svn:keywords foo.c Author Date Rev

The same goes for a revision property:

$ svn propget svn:log --revprop -r 20 Began journal.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn propeditя‘®¤Ґа¦ ­ЁҐяsvn proplist



You can use proplist to see the properties on an item in your working copy:

$ svn proplist foo.c Properties on 'foo.c': svn:mime-type svn:keywords owner

But with the --verbose flag, svn proplist is extremely handy as it also shows you the values for the properties:

$ svn proplist --verbose foo.c Properties on 'foo.c': svn:mime-type : text/plain svn:keywords : Author Date Rev owner : sally
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn propgetя‘®¤Ґа¦ ­ЁҐяsvn propset



Set the mimetype on a file:

$ svn propset svn:mime-type image/jpeg foo.jpg property 'svn:mime-type' set on 'foo.jpg'

On a UNIX system, if you want a file to have the executable permission set:

$ svn propset svn:executable ON somescript property 'svn:executable' set on 'somescript'

Perhaps you have an internal policy to set certain properties for the benefit of your coworkers:

$ svn propset owner sally foo.c property 'owner' set on 'foo.c'

If you made a mistake in a log message for a particular revision and want to change it, use --revprop and set svn:log to the new log message:

$ svn propset --revprop -r 25 svn:log "Journaled about trip to New York." property 'svn:log' set on repository revision '25'

Or, if you don't have a working copy, you can provide a URL.

$ svn propset --revprop -r 26 svn:log "Document nap." http://svn.red-bean.com/repos property 'svn:log' set on repository revision '25'

Lastly, you can tell propset to take its input from a file. You could even use this to set the contents of a property to something binary:

$ svn propset owner-pic -F sally.jpg moo.c property 'owner-pic' set on 'moo.c'


If you get a conflict on an update, your working copy will sprout three new files:

$ svn update C foo.c Updated to revision 31. $ ls foo.c foo.c.mine foo.c.r30 foo.c.r31

Once you've resolved the conflict and foo.c is ready to be committed, run svn resolved to let your working copy know you've taken care of everything.




Discard changes to a file:

$ svn revert foo.c Reverted foo.c

If you want to revert a whole directory of files, use the --recursive flag:

$ svn revert --recursive . Reverted newdir/afile Reverted foo.c Reverted bar.txt

Lastly, you can undo any scheduling operations:

$ svn add mistake.txt whoops A mistake.txt A whoops A whoops/oopsie.c $ svn revert mistake.txt whoops Reverted mistake.txt Reverted whoops $ svn status ? mistake.txt ? whoops


This is the easiest way to find out what changes you have made to your working copy:

$ svn status wc M wc/bar.c A + wc/qax.c

If you want to find out what files in your working copy are out-of-date, pass the --show-updates switch (this will not make any changes to your working copy). Here you can see that wc/foo.c has changed in the repository since we last updated our working copy:

$ svn status --show-updates wc M 965 wc/bar.c * 965 wc/foo.c A + 965 wc/qax.c Status against revision: 981


If you're currently inside the directory vendors which was branched to vendors-with-fix and you'd like to switch your working copy to that branch:

$ svn switch http://svn.red-bean.com/repos/branches/vendors-with-fix . U myproj/foo.txt U myproj/bar.txt U myproj/baz.c U myproj/qux.c Updated to revision 31.

And to switch back, just provide the URL to the location in the repository from which you originally checked out your working copy:

$ svn switch http://svn.red-bean.com/repos/trunk/vendors . U myproj/foo.txt U myproj/bar.txt U myproj/baz.c U myproj/qux.c Updated to revision 31.


Unlock two files in your working copy:

$ svn unlock tree.jpg house.jpg 'tree.jpg' unlocked. 'house.jpg' unlocked.

Unlock a file in your working copy that is currently locked by another user:

$ svn unlock tree.jpg svn: 'tree.jpg' is not locked in this working copy $ svn unlock --force tree.jpg 'tree.jpg' unlocked.

Unlock a file without a working copy:

$ svn unlock http://svn.red-bean.com/repos/test/tree.jpg 'tree.jpg unlocked.

For further details, see .

ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svn switchя‘®¤Ґа¦ ­ЁҐяsvn update



Pick up repository changes that have happened since your last update:

$ svn update A newdir/toggle.c A newdir/disclose.c A newdir/launch.c D newdir/README Updated to revision 32.

You can also update your working copy to an older revision (Subversion doesn't have the concept of files like CVS does; see ЏаЁ«®¦Ґ­ЁҐяA, Subversion ¤«п Ї®«м§®ў вҐ«Ґ© CVS):

$ svn update -r30 A newdir/README D newdir/toggle.c D newdir/disclose.c D newdir/launch.c U foo.c Updated to revision 30.


Creating a new repository is just this easy:

$ svnadmin create /usr/local/svn/repos

In Subversion 1.0, a Berkeley DB repository is always created. In Subversion 1.1, a Berkeley DB repository is the default repository type, but an FSFS repository can be created using the --fs-type option:

$ svnadmin create /usr/local/svn/repos --fs-type fsfs

[55] Remember, svnadmin works only with local paths, not URLs.

ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadminя‘®¤Ґа¦ ­ЁҐяsvnadmin deltify



Dump your whole repository:

$ svnadmin dump /usr/local/svn/repos SVN-fs-dump-format-version: 1 Revision-number: 0 * Dumped revision 0. Prop-content-length: 56 Content-length: 56 :

Incrementally dump a single transaction from your repository:

$ svnadmin dump /usr/local/svn/repos -r 21 --incremental * Dumped revision 21. SVN-fs-dump-format-version: 1 Revision-number: 21 Prop-content-length: 101 Content-length: 101 :
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin deltifyя‘®¤Ґа¦ ­ЁҐяsvnadmin help



Remove all unused log files from a repository:

$ svnadmin list-unused-dblogs /path/to/repos /path/to/repos/log.0000000031 /path/to/repos/log.0000000032 /path/to/repos/log.0000000033 $ svnadmin list-unused-dblogs /path/to/repos | xargs rm ## disk space reclaimed!
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin list-dblogsя‘®¤Ґа¦ ­ЁҐяsvnadmin load



List all outstanding transactions in a repository.

$ svnadmin lstxns /usr/local/svn/repos/ 1w 1x
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin lslocksя‘®¤Ґа¦ ­ЁҐяsvnadmin recover



Recover a hung repository:

$ svnadmin recover /usr/local/svn/repos/ Repository lock acquired. Please wait; recovering the repository may take some time... Recovery completed. The latest repos revision is 34.

Recovering the database requires an exclusive lock on the repository. If another process is accessing the repository, then svnadmin recover will error:

$ svnadmin recover /usr/local/svn/repos svn: Failed to get exclusive repository access; perhaps another process such as httpd, svnserve or svn has it open? $

The --wait option, however, will cause svnadmin recover to wait indefinitely for other processes to disconnect:

$ svnadmin recover /usr/local/svn/repos --wait Waiting on repository lock; perhaps another process has it open? ### time goes by... Repository lock acquired. Please wait; recovering the repository may take some time... Recovery completed. The latest repos revision is 34.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin lstxnsя‘®¤Ґа¦ ­ЁҐяsvnadmin rmlocks



Remove named transactions:

$ svnadmin rmtxns /usr/local/svn/repos/ 1w 1x

Fortunately, the output of lstxns works great as the input for rmtxns:

$ svnadmin rmtxns /usr/local/svn/repos/ `svnadmin lstxns /usr/local/svn/repos/`

Which will remove all uncommitted transactions from your repository.

ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin rmlocksя‘®¤Ґа¦ ­ЁҐяsvnadmin setlog



Set the log message for revision 19 to the contents of the file msg:

$ svnadmin setlog /usr/local/svn/repos/ -r 19 msg
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin rmtxnsя‘®¤Ґа¦ ­ЁҐяsvnadmin verify



Verify a hung repository:

$ svnadmin verify /usr/local/svn/repos/ * Verified revision 1729.
ЏаҐ¤.я“а®ўҐ­м ўлиҐя‘«Ґ¤.
svnadmin setlogя‘®¤Ґа¦ ­ЁҐяsvnlook


External diff


Subversion calls external diff programs with parameters suitable for the GNU diff utility, and expects only that the external program return with a successful error code. For most alternative diff program, only the sixth and seventh arguments, the paths of the files which represent the left and right sides of the diff, respectively, are of interest. Note that Subversion runs the diff program once per modified file covered by the Subversion operation, so if your program runs in an asynchronous fashion (or «backgrounded»), you might have several instances of it all running simultaneously. Finally, Subversion expects that your program return an errorcode of 0 if your program detected differences, or 1 if it did not—any other errorcode is considered a fatal error. [46]

Пример 7.2, «diffwrap.sh» and Пример 7.3, «diffwrap.bat» are templates for external diff tool wrappers in the Bourne shell and Windows batch scripting languages, respectively.

Пример 7.2. diffwrap.sh

#!/bin/sh # Configure your favorite diff program here. DIFF="/usr/local/bin/my-diff-tool" # Subversion provides the paths we need as the sixth and seventh # parameters. LEFT=${6} RIGHT=${7} # Call the diff command (change the following line to make sense for # your merge program). $DIFF --left $LEFT --right $RIGHT # Return an errorcode of 0 if no differences were detected, 1 if some were. # Any other errorcode will be treated as fatal.

Пример 7.3. diffwrap.bat

@ECHO OFF REM Configure your favorite diff program here. SET DIFF="C:\Program Files\Funky Stuff\My Diff Tool.exe" REM Subversion provides the paths we need as the sixth and seventh REM parameters. SET LEFT=%6 SET RIGHT=%7 REM Call the diff command (change the following line to make sense for REM your merge program). %DIFF% --left %LEFT% --right %RIGHT% REM Return an errorcode of 0 if no differences were detected, 1 if some were. REM Any other errorcode will be treated as fatal.


Subversion calls external merge programs with parameters suitable for the GNU diff3 utility, expecting that the external program return with a successful error code and that the full file contents which result from the completed merge operation are printed on the standard output stream (so that Subversion can redirect them into the appropriate version controlled file). For most alternative merge programs, only the ninth, tenth, and eleventh arguments, the paths of the files which represent the «mine», «older», and «yours» inputs, respectively, are of interest. Note that because Subversion depends on the output of your merge program, you wrapper script must not exit before that output has been delivered to Subversion. When it finally does exit, it should return an errorcode of 0 if the merge was successful, or 1 if unresolved conflicts remain in the output—any other errorcode is considered a fatal error.

Пример 7.4, «diff3wrap.sh» and Пример 7.5, «diff3wrap.bat» are templates for external merge tool wrappers in the Bourne shell and Windows batch scripting languages, respectively.

Пример 7.4. diff3wrap.sh

#!/bin/sh # Configure your favorite diff3/merge program here. DIFF3="/usr/local/bin/my-merge-tool" # Subversion provides the paths we need as the ninth, tenth, and eleventh # parameters. MINE=${9} OLDER=${10} YOURS=${11} # Call the merge command (change the following line to make sense for # your merge program). $DIFF3 --older $OLDER --mine $MINE --yours $YOURS # After performing the merge, this script needs to print the contents # of the merged file to stdout. Do that in whatever way you see fit. # Return an errorcode of 0 on successful merge, 1 if unresolved conflicts # remain in the result. Any other errorcode will be treated as fatal. Пример 7.5. diff3wrap.bat

@ECHO OFF REM Configure your favorite diff3/merge program here. SET DIFF3="C:\Program Files\Funky Stuff\My Merge Tool.exe" REM Subversion provides the paths we need as the ninth, tenth, and eleventh REM parameters. But we only have access to nine parameters at a time, so we REM shift our nine-parameter window twice to let us get to what we need. SHIFT SHIFT SET MINE=%7 SET OLDER=%8 SET YOURS=%9 REM Call the merge command (change the following line to make sense for REM your merge program). %DIFF3% --older %OLDER% --mine %MINE% --yours %YOURS% REM After performing the merge, this script needs to print the contents REM of the merged file to stdout. Do that in whatever way you see fit. REM Return an errorcode of 0 on successful merge, 1 if unresolved conflicts REM remain in the result. Any other errorcode will be treated as fatal.
[45] Subversion developers are good, but even the best make mistakes.

[46] The GNU diff manual page puts it this way: «An exit status of 0 means no differences were found, 1 means some differences were found, and 2 means trouble.»

Пред. Уровень выше След.
Localization Содержание Subversion Repository URLs


Externals Definitions


Sometimes it is useful to construct a working copy that is made out of a number of different checkouts. For example, you may want different subdirectories to come from different locations in a repository, or perhaps from different repositories altogether. You could certainly setup such a scenario by hand—using svn checkout to create the sort of nested working copy structure you are trying to achieve. But if this layout is important for everyone who uses your repository, every other user will need to perform the same checkout operations that you did.

Fortunately, Subversion provides support for externals definitions. An externals definition is a mapping of a local directory to the URL—and possibly a particular revision—of a versioned resource. In Subversion, you declare externals definitions in groups using the svn:externals property. You can create or modify this property using svn propset or svn propedit (see «Зачем нужны свойства?»). It can be set on any versioned directory, and its value is a multi-line table of subdirectories (relative to the versioned directory on which the property is set) and fully qualified, absolute Subversion repository URLs.

$ svn propget svn:externals calc third-party/sounds http://sounds.red-bean.com/repos third-party/skins http://skins.red-bean.com/repositories/skinproj third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker

The convenience of the svn:externals property is that once it is set on a versioned directory, everyone who checks out a working copy with that directory also gets the benefit of the externals definition. In other words, once one person has made the effort to define those nested working copy checkouts, no one else has to bother—Subversion will, upon checkout of the original working copy, also checkout the external working copies.

Note the previous externals definition example. When someone checks out a working copy of the calc directory, Subversion also continues to checkout the items found in its externals definition.

$ svn checkout http://svn.example.com/repos/calc A calc A calc/Makefile A calc/integer.c A calc/button.c Checked out revision 148. Fetching external item into calc/third-party/sounds A calc/third-party/sounds/ding.ogg A calc/third-party/sounds/dong.ogg A calc/third-party/sounds/clang.ogg … A calc/third-party/sounds/bang.ogg A calc/third-party/sounds/twang.ogg Checked out revision 14. Fetching external item into calc/third-party/skins …

If you need to change the externals definition, you can do so using the regular property modification subcommands. When you commit a change to the svn:externals property, Subversion will synchronize the checked-out items against the changed externals definition when you next run svn update. The same thing will happen when others update their working copies and receive your changes to the externals definition.

The svn status command also recognizes externals definitions, displaying a status code of X for the disjoint subdirectories into which externals are checked out, and then recursing into those subdirectories to display the status of the external items themselves.



Формат


svn add PATH...



svn blame TARGET[@REV]...




svn cat TARGET[@REV]...




svn checkout URL[@REV]... [PATH]




svn cleanup [PATH...]




svn commit [PATH...]




svn copy SRC DST



From Ben Collins-Sussman


Thanks to my wife Frances, who, for many months, got to hear, «But honey, I'm still working on the book», rather than the usual, «But honey, I'm still doing email.» I don't know where she gets all that patience! She's my perfect counterbalance.

Thanks to my extended family for their sincere encouragement, despite having no actual interest in the subject. (You know, the ones who say, «Ooh, you're writing a book?», and then when you tell them it's a computer book, sort of glaze over.)

Thanks to all my close friends, who make me a rich, rich man. Don't look at me that way—you know who you are.



From Brian W. Fitzpatrick


Huge thanks to my wife Marie for being incredibly understanding, supportive, and most of all, patient. Thank you to my brother Eric who first introduced me to UNIX programming way back when. Thanks to my Mom and Grandmother for all their support, not to mention enduring a Christmas holiday where I came home and promptly buried my head in my laptop to work on the book.

To Mike and Ben: It was a pleasure working with you on the book. Heck, it's a pleasure working with you at work!

To everyone in the Subversion community and the Apache Software Foundation, thanks for having me. Not a day goes by where I don't learn something from at least one of you.

Lastly, thanks to my Grandfather who always told me that «freedom equals responsibility.» I couldn't agree more.



From C. Michael Pilato


Special thanks to my wife, Amy, for her love and patient support, for putting up with late nights, and for even reviewing entire sections of this book—you always go the extra mile, and do so with incredible grace. Gavin, when you're old enough to read, I hope you're as proud of your Daddy as he is of you. Mom and Dad (and the rest of the family), thanks for your constant support and enthusiasm.

Hats off to Shep Kendall, through whom the world of computers was first opened to me; Ben Collins-Sussman, my tour-guide through the open-source world; Karl Fogel—you are my .emacs; Greg Stein, for oozing practical programming know-how; Brian Fitzpatrick—for sharing this writing experience with me. To the many folks from whom I am constantly picking up new knowledge—keep dropping it!

Finally, to the One who perfectly demonstrates creative excellence—thank you.


[3] Oh, and thanks, Karl, for being too overworked to write this book yourself.

Пред. Уровень выше След.
Эта книга распространяется свободно Содержание Глава 1. Введение


Функциональные ветки


Функциональная ветка является доминирующим примером в этой главе, над такой веткой вы работаете пока Салли работает над /trunk. Это временная ветка, которая создается для работы над комплексным изменением без пересечения со стабильной линией разработки /trunk. В отличие от веток релизов (которые могут поддерживаться вечно), функциональные ветки создаются, используются, внедряются обратно в главную линию разработки, после чего полностью удаляются. Они имеют ограниченный срок использования.

Опять же, правила проекта относительно определения момента, когда требуется создание функциональной ветки могут быть разными. Некоторые проекты вообще никогда не используют функциональные ветки: все фиксируется в /trunk. Преимущества такой системы в ее простоте — никому не нужно учиться делать ветки или объединения. Недостатком является то, что главная линия разработки часто не стабильна или не пригодна к использованию. В других проектах ветки используют по-другому: ни одного изменения не фиксируют в главной линии разработки напрямую. Даже для самых простых изменений создается краткосрочная ветка, внимательно анализируется и объединяется с главной линией. После чего ветка удаляется. Ценой огромных накладных расходов, такая система гарантирует исключительную стабильность и пригодность к использованию главной линии разработки в любой момент времени.

Большинство проектов использует что-то среднее. Как правило, все время контролируя, что /trunk компилируется и проходит регрессивные тесты. Функциональная ветка требуется только тогда, когда изменение требует большого количества дестабилизирующих фиксаций. Хорошим способом проверки является постановка такого вопроса: если разработчик работал несколько дней изолировано, а затем за один раз зафиксировал большое изменение (притом, что /trunk не будет дестабилизирован) будет ли сложно отследить это изменение? Если ответ на этот вопрос «да», то тогда изменение должно разрабатываться в функциональной ветке. По мере того, как разработчик последовательно фиксирует изменения в ветку, они могут легко отслеживаться другими участниками.

Напоследок, рекомендация, как по ходу работы лучше всего сохранять функциональную ветку «синхронизированной» с главной линией разработки. Как мы уже говорили, рискованно работать над веткой в течение недель или месяцев; изменения в главной линии будут продолжаться, и настанет момента, когда две линии разработки станут отличаться так сильно, что попытка объединить ветку обратно с главной линией разработки может стать ночным кошмаром.

Этой ситуации не возникнет, если регулярно объединять ветку с изменениями в главной линии. Возьмите за правило один раз в неделю объединять с веткой значимые изменения в главной линии разработки за прошедшую неделю. Делайте это аккуратно; за объединением необходим ручной контроль для того, что бы исключить проблему повторных объединений (как это описано в разделе «Ручной контроль слияния»). Необходимо внимательно записывать лог сообщение, указывая какой именно диапазон правок был объединен (как показано в разделе «Полное объединение двух веток»). Возможно это звучит устрашающе, но на самом деле это сделать очень легко.

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

$ cd trunk-working-copy $ svn update At revision 1910. $ svn merge http://svn.example.com/repos/calc/trunk@1910 \ http://svn.example.com/repos/calc/branches/mybranch@1910 U real.c U integer.c A newdirectory A newdirectory/newfile …

Сравнивая правку HEAD главной линии разработки и правку HEAD ветки, определяется дельта, которая представляет собой только изменения сделанные в ветке; обе линии разработки уже содержат все изменения из главной линии.

Другим способом представления этого приема является то, что еженедельная синхронизация ветки аналогична запуску svn update в рабочей копии, в то время как окончательное объединение аналогично запуску из рабочей копии svn commit. В конце концов, что же такое рабочая копия если не миниатюрная личная ветка? Эта такая ветка которая способна хранить одно изменение в каждый момент времени.


[15] Однако, проект Subversion планирует со временем реализовать команду svnadmin obliterate с помощью которой можно будет выборочно удалять информацию. А пока за возможным решением проблемы обратитесь к разделу «svndumpfilter».

[16] Из-за того, что CVS не версионирует деревья, она создает область Attic для каждой директории хранилища как способ запоминания удаленных файлов.

Пред. Уровень выше След.
Копирование изменений между ветками Содержание Переключение рабочей копии


General Vendor Branch Management Procedure


Managing vendor branches generally works like this. You create a top-level directory (such as /vendor) to hold the vendor branches. Then you import the third party code into a subdirectory of that top-level directory. You then copy that subdirectory into your main development branch (for example, /trunk) at the appropriate location. You always make your local changes in the main development branch. With each new release of the code you are tracking you bring it into the vendor branch and merge the changes into /trunk, resolving whatever conflicts occur between your local changes and the upstream changes.

Perhaps an example will help to clarify this algorithm. We'll use a scenario where your development team is creating a calculator program that links against a third-party complex number arithmetic library, libcomplex. We'll begin with the initial creation of the vendor branch, and the import of the first vendor drop. We'll call our vendor branch directory libcomplex, and our code drops will go into a subdirectory of our vendor branch called current. And since svn import creates all the intermediate parent directories it needs, we can actually accomplish both of these steps with a single command.

$ svn import /path/to/libcomplex-1.0 \ http://svn.example.com/repos/vendor/libcomplex/current \ -m 'importing initial 1.0 vendor drop' …

We now have the current version of the libcomplex source code in /vendor/libcomplex/current. Now, we tag that version (see «Метки») and then copy it into the main development branch. Our copy will create a new directory called libcomplex in our existing calc project directory. It is in this copied version of the vendor data that we will make our customizations.

$ svn copy http://svn.example.com/repos/vendor/libcomplex/current \ http://svn.example.com/repos/vendor/libcomplex/1.0 \ -m 'tagging libcomplex-1.0' … $ svn copy http://svn.example.com/repos/vendor/libcomplex/1.0 \ http://svn.example.com/repos/calc/libcomplex \ -m 'bringing libcomplex-1.0 into the main branch' …

We check out our project's main branch—which now includes a copy of the first vendor drop—and we get to work customizing the libcomplex code. Before we know it, our modified version of libcomplex is now completely integrated into our calculator program. [44]

A few weeks later, the developers of libcomplex release a new version of their library—version 1.1—which contains some features and functionality that we really want. We'd like to upgrade to this new version, but without losing the customizations we made to the existing version. What we essentially would like to do is to replace our current baseline version of libcomplex 1.0 with a copy of libcomplex 1.1, and then re-apply the custom modifications we previously made to that library to the new version. But we actually approach the problem from the other direction, applying the changes made to libcomplex between versions 1.0 and 1.1 to our modified copy of it.

To perform this upgrade, we checkout a copy of our vendor branch, and replace the code in the current directory with the new libcomplex 1.1 source code. We quite literally copy new files on top of existing files, perhaps exploding the libcomplex 1.1 release tarball atop our existing files and directories. The goal here is to make our current directory contain only the libcomplex 1.1 code, and to ensure that all that code is under version control. Oh, and we want to do this with as little version control history disturbance as possible.

After replacing the 1.0 code with 1.1 code, svn status will show files with local modifications as well as, perhaps, some unversioned or missing files. If we did what we were supposed to do, the unversioned files are only those new files introduced in the 1.1 release of libcomplex—we run svn add on those to get them under version control. The missing files are files that were in 1.0 but not in 1.1, and on those paths we run svn delete. Finally, once our current working copy contains only the libcomplex 1.1 code, we commit the changes we made to get it looking that way.

Our current branch now contains the new vendor drop. We tag the new version (in the same way we previously tagged the version 1.0 vendor drop), and then merge the differences between the tag of the previous version and the new current version into our main development branch.

$ cd working-copies/calc $ svn merge http://svn.example.com/repos/vendor/libcomplex/1.0 \ http://svn.example.com/repos/vendor/libcomplex/current \ libcomplex … # resolve all the conflicts between their changes and our changes $ svn commit -m 'merging libcomplex-1.1 into the main branch' …

In the trivial use case, the new version of our third-party tool would look, from a files-and-directories point of view, just like the previous version. None of the libcomplex source files would have been deleted, renamed or moved to different locations—the new version would contain only textual modifications against the previous one. In a perfect world, our modifications would apply cleanly to the new version of the library, with absolutely no complications or conflicts.

But things aren't always that simple, and in fact it is quite common for source files to get moved around between releases of software. This complicates the process of ensuring that our modifications are still valid for the new version of code, and can quickly degrade into a situation where we have to manually recreate our customizations in the new version. Once Subversion knows about the history of a given source file—including all its previous locations—the process of merging in the new version of the library is pretty simple. But we are responsible for telling Subversion how the source file layout changed from vendor drop to vendor drop.



Get the Source Code


To edit the code, you need to have the code. This means you need to check out a working copy from the public Subversion source repository. As straightforward as that might sound, the task can be slightly tricky. Because Subversion's source code is versioned using Subversion itself, you actually need to «bootstrap» by getting a working Subversion client via some other method. The most common methods include downloading the latest binary distribution (if such is available for your platform), or downloading the latest source tarball and building your own Subversion client. If you build from source, make sure to read the INSTALL file in the top level of the source tree for instructions.

After you have a working Subversion client, you are now poised to checkout a working copy of the Subversion source repository from http://svn.collab.net/repos/svn/trunk/: [51]

$ svn checkout http://svn.collab.net/repos/svn/trunk subversion A subversion/HACKING A subversion/INSTALL A subversion/README A subversion/autogen.sh A subversion/build.conf …

The above command will checkout the bleeding-edge, latest version of the Subversion source code into a subdirectory named subversion in your current working directory. Obviously, you can adjust that last argument as you see fit. Regardless of what you call the new working copy directory, though, after this operation completes, you will now have the Subversion source code. Of course, you will still need to fetch a few helper libraries (apr, apr-util, etc.)—see the INSTALL file in the top level of the working copy for details.



История SubversionВозможности SubversionАрхитектура SubversionУстановка SubversionКомпоненты


Содержание
Что такое Subversion? История SubversionВозможности SubversionАрхитектура SubversionУстановка SubversionКомпоненты SubversionБыстрый стартУправление версиями — это искусство управления изменяющейся информацией. Долгое время оно было жизненно важным инструментом программистов, которые обычно проводят время, внося небольшие изменения в программы, а в один прекрасный момент делают откат изменений, возвращаясь к предыдущей версии. Однако, полезность систем управления версиями выходит далеко за пределы мира разработчиков программного обеспечения. Управление версиями требуется повсюду, где можно встретить людей, использующих компьютер для работы с постоянно изменяющейся информацией. Именно тогда на сцену выходит Subversion.
В этой главе даётся общее введение в Subversion. Здесь поясняется, что это такое, что она делает и как её получить.

Основные понятия


Содержание

ХранилищеМодели версионированияПроблема разделения файловМодель Блокирование-Изменение-РазблокированиеМодель Копирование-Изменение-СлияниеSubversion в действииРабочие копииПравкиКак рабочие копии отслеживают хранилищеСмешивание правок в рабочих копияхОбновления и фиксации отделены друг от другаСмешивание правок — это нормальноСмешивание правок — это полезноСмешивание правок имеет ограниченияПодводя итоги

Эта глава представляет собой краткое, промежуточное введение в Subversion. Если контроль версий для вас в новинку, то эта глава специально для вас. Мы начнем с обсуждения основных понятий контроля версий, подойдем к основным идеям, лежащим в основе Subversion и покажем несколько простых примеров использования Subversion.

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



Ветвление и слияние


Содержание

Что такое ветка?Использование ветокСоздание веткиРабота с веткойКлючевые идеи, стоящие за веткамиКопирование изменений между веткамиКопирование отдельных измененийКлючевые понятия, стоящие за слияниемКак правильнее всего использовать слияниеРучной контроль слиянияПредварительные просмотр при объединенииКонфликты при объединенииУчитывать или игнорировать происхождениеТиповые примеры использованияПолное объединение двух ветокОтмена измененийВосстановление удаленных элементовТиповые приемы при использовании ветокВетки релизовФункциональные веткиПереключение рабочей копииМеткиСоздание простой меткиСоздание комплексной меткиПоддержка ветокСтруктура хранилищаПродолжительность жизни информацииПодводя итоги

Ветвление, назначение меток и слияние понятия свойственные практически всем системам управления версиями. Если вы плохо знакомы с этими понятиями, то в этой главе мы предлагаем хорошее введение. Если эти понятия вам знакомы, тогда надеемся что вам будет интересно узнать как эти идеи реализует Subversion.

Ветвление это фундаментальное понятие управления версиями. Если вы доверии Subversion управлять своей информацией, то эта функция от которой со временем вы будете зависеть. Эта глава предполагает, что вы уже знакомы с основными понятиями Subversion (Глава 2, Основные понятия).



Профессиональное использование Subversion


Содержание

Параметры времени выполненияСтруктура области конфигурацииКонфигурация и реестр WindowsПараметры конфигурацииServersConfigСвойстваЗачем нужны свойства?Использование свойствСпециальные свойстваsvn:executablesvn:mime-typesvn:ignoresvn:keywordssvn:eol-stylesvn:externalssvn:specialsvn:needs-lockAutomatic Property SettingLockingCreating locksDiscovering locksBreaking and stealing locksLock CommunicationPeg and Operative RevisionsExternals DefinitionsVendor branchesGeneral Vendor Branch Management Proceduresvn_load_dirs.plLocalizationUnderstanding localesSubversion's use of localesUsing External Differencing ToolsExternal diffExternal diff3Subversion Repository URLs

Если эту книгу вы читали главу за главой, от начала до конца, то к настоящему моменту должны иметь достаточно знаний для использования Subversion клиента при выполнении типичных управлению версиями операций. Вы понимаете, как создавать рабочую копию. Знаете как используя команды svn commit и svn update отправлять и получать изменения. Возможно у вас уже даже выработался рефлекс бессознательного запуска svn status. Вы готовы применять Subversion в большинстве возможных типовых ситуаций.

Однако предоставляемая Subversion функциональность не ограничивается «типовыми операциями управления версиями».

Эта глава рассказывает о не часто используемых возможностях Subversion. В ней мы рассмотрим поддержку свойств (или «метаданных») и способы изменения стандартного поведения Subversion изменяя ее параметры времени выполнения. Мы расскажем как используя внешние зависимости заставить Subversion получать информацию из нескольких хранилищ. Подробно рассмотрим клиентские и серверные инструменты, входящие в поставку Subversion.

Перед чтением этой главы, необходимо хорошо представлять механизмы версионированния файлов и директорий в Subversion. Если вы еще этого не прочитали или просто хотите освежить в памяти эту информацию, рекомендуем просмотреть Глава 2, Основные понятия и Глава 3, Экскурсия по Subversion. После того как вы овладеете основами и примами, рассмотренными в этой главе, вы станете продвинутым пользователем Subversion!



Информация для разработчиков


Содержание

Layered Library DesignRepository LayerRepository Access LayerRA-DAV (Repository Access Using HTTP/DAV)RA-SVN (Custom Protocol Repository Access)RA-Local (Direct Repository Access)Your RA Library HereClient LayerUsing the APIsThe Apache Portable Runtime LibraryURL and Path RequirementsUsing Languages Other than C and C++Inside the Working Copy Administration AreaThe Entries FilePristine Copies and Property FilesWebDAVProgramming with Memory PoolsContributing to SubversionJoin the CommunityGet the Source CodeBecome Familiar with Community PoliciesMake and Test Your ChangesDonate Your Changes

Subversion is an open-source software project developed under an Apache-style software license. The project is financially backed by CollabNet, Inc., a California-based software development company. The community that has formed around the development of Subversion always welcomes new members who can donate their time and attention to the project. Volunteers are encouraged to assist in any way they can, whether that means finding and diagnosing bugs, refining existing source code, or fleshing out whole new features.

This chapter is for those who wish to assist in the continued evolution of Subversion by actually getting their hands dirty with the source code. We will cover some of the software's more intimate details, the kind of technical nitty-gritty that those developing Subversion itself—or writing entirely new tools based on the Subversion libraries—should be aware of. If you don't foresee yourself participating with the software at such a level, feel free to skip this chapter with confidence that your experience as a Subversion user will not be affected.



Полное справочное руководство по Subversion


Содержание

Клиент командной строки Subversion: svnПараметры svnПодкоманды svnsvn addsvn blamesvn catsvn checkoutsvn cleanupsvn commitsvn copysvn deletesvn diffsvn exportsvn helpsvn importsvn infosvn listsvn locksvn logsvn mergesvn mkdirsvn movesvn propdelsvn propeditsvn propgetsvn proplistsvn propsetsvn resolvedsvn revertsvn statussvn switchsvn unlocksvn updatesvnadminsvnadmin Switchessvnadmin Subcommandssvnadmin createsvnadmin deltifysvnadmin dumpsvnadmin helpsvnadmin hotcopysvnadmin list-dblogssvnadmin list-unused-dblogssvnadmin loadsvnadmin lslockssvnadmin lstxnssvnadmin recoversvnadmin rmlockssvnadmin rmtxnssvnadmin setlogsvnadmin verifysvnlooksvnlook Switchessvnlooksvnlook authorsvnlook catsvnlook changedsvnlook datesvnlook diffsvnlook dirs-changedsvnlook helpsvnlook historysvnlook infosvnlook locksvnlook logsvnlook propgetsvnlook proplistsvnlook treesvnlook uuidsvnlook youngestsvnservesvnserve Switchessvnversionsvnversionmod_dav_svnmod_dav_svn Configuration Directives

Эта глава является полным справочным руководством по использованию Subversion. Она описывает работу программы-клиента командной строки (svn) и всех его подкоманд, а так же программы администрирования хранилища (svnadmin и svnlook) и соответствующие им подкоманды.



Хранилище


Subversion является централизованной системой для разделения информации. В ее основе хранилище, являющееся центром хранения данных. Хранилище хранит информацию в форме дерева файлов — типичном представлении файлов и каталогов. Любое количество клиентов подключается к хранилищу и читает или записывает эти файлы. Записывая данные, клиент делает информацию доступной для остальных; читая данные клиент получает информацию от других. Рисунок 2.1, «Типичная клиент/серверная система» иллюстрирует это.

Рисунок 2.1. Типичная клиент/серверная система

Почему мы заостряем на этом внимание? Пока это звучит как определение типичного файл-сервера. И действительно, хранилище является разновидностью файл-сервера, однако не совсем обычного. Что делает хранилище Subversion особенным — это то, что он запоминает каждое внесенное изменение: любое изменение любого файла, равно как изменения в самом дереве каталогов, такие как добавление, удаление и реорганизация файлов и каталогов.

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

Пред.   След.
Быстрый старт Содержание Модели версионирования


Inside the Working Copy Administration Area


As we mentioned earlier, each directory of a Subversion working copy contains a special subdirectory called .svn which houses administrative data about that working copy directory. Subversion uses the information in .svn to keep track of things like:

Which repository location(s) are represented by the files and subdirectories in the working copy directory.

What revision of each of those files and directories are currently present in the working copy.

Any user-defined properties that might be attached to those files and directories.

Pristine (un-edited) copies of the working copy files.

While there are several other bits of data stored in the .svn directory, we will examine only a couple of the most important items.



Использование свойств


Команда svn предоставляет несколько способов добавления или изменения свойств файлов и директорий. Свойства с короткими, читаемыми значениями, наверное проще всего добавить указав имя и значение свойства в командной строке подкоманды propset.

$ svn propset copyright '(c) 2003 Red-Bean Software' calc/button.c property 'copyright' set on 'calc/button.c' $

Однако мы уже знаем о гибкости, предлагаемой Subversion для значений свойств. И если вам необходимо иметь многострочное текстовое, или даже бинарное значение свойства, передавать такое значение через командную строку не удобно. Для таких случаев команда propset имеет параметр --file (-F), указывающий имя файла, содержащего новое значение свойства.

$ svn propset license -F /path/to/LICENSE calc/button.c property 'license' set on 'calc/button.c' $

Для имен свойств существует ряд ограничений. Имя свойства должно начинаться с буквы, двоеточия (:) или подчеркивания (_); дальше можно использовать цифры, тире (-) и точки (.). [36]

Дополнительно к команде propset, svn имеет команду propedit. Эта команда использует для добавления или изменения свойств указанную программу-редактор (см. «Config»). При выполнении команды, svn вызывает редактор с временным файлом, содержащим текущее значение свойства (или с пустым файлом, если добавляется новое свойство). Затем вы просто меняете в редакторе значение, пока оно не станет таким, каким бы вы хотели его видеть, сохраняете временный файл и выходите из редактора. Если Subversion обнаружит, что вы действительно изменили существующие значение свойства, будет установлено новое значение. Если вы вышли из редактора не внеся изменений, модификации свойства не произойдет.

$ svn propedit copyright calc/button.c ### exit the editor without changes No changes to property 'copyright' on 'calc/button.c' $

Обращаем ваше внимание на то, что как и другие команды svn, команды, относящиеся к свойствам могут применяться к нескольким путям за раз. Это дает возможность одной командой изменять свойства целого набора файлов. Например, можно сделать вот так:

$ svn propset copyright '(c) 2002 Red-Bean Software' calc/* property 'copyright' set on 'calc/Makefile' property 'copyright' set on 'calc/button.c' property 'copyright' set on 'calc/integer.c' … $

Все эти добавления и редактирования свойств не очень полезны, если нельзя просто узнать значение свойства. Поэтому для показа сохраненных для файлов и директорий имен и значений свойств, программа svn предлагает две подкоманды. Команда svn proplist перечисляет существующие для указанного пути свойства. После того как вы знаете имя свойства, можно, используя svn propget, запросить его значение. Эта команда выведет на стандартный поток ввода-вывода значение свойства для элемента по указанному пути (или путями) и с указанным именем.

$ svn proplist calc/button.c Properties on 'calc/button.c': copyright license $ svn propget copyright calc/button.c (c) 2003 Red-Bean Software

Существует даже вариант команды proplist, который перечисляет как имена, так и значения свойств. Просто добавьте параметр --verbose (-v).

$ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software license : ================================================================ Copyright (c) 2003 Red-Bean Software. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the recipe for Fitz's famous red-beans-and-rice. …

Последней, относящейся к свойствам подкомандой является propdel. Не смотря на то, что Subversion позволяет сохранять свойства с пустыми значениями, полностью удалить свойство, используя propedit или propset, нельзя. Например, такая команда не даст желаемого эффекта:

$ svn propset license '' calc/button.c property 'license' set on 'calc/button.c' $ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software license : $

Для полного удаления свойств необходимо использовать команду propdel. Ее синтаксис такой же как и у других команд работы со свойствами:

$ svn propdel license calc/button.c property 'license' deleted from ''. $ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software $

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

Редактирование свойств правок

Помните, мы говорили о неверсионированных свойствах правок? Их то же можно менять с помощью svn. Просто добавьте параметр командной строки --revprop и укажите правку, чье свойство вы хотите изменить. Учитывая глобальность правок, в этом случае не нужно указывать путь, так как вы находитесь в рабочей копии хранилища, в котором вы хотите изменить свойство правки. Например, может понадобиться заменить лог-сообщение фиксации в существующей правке. [37]

$ svn propset svn:log '* button.c: Fix a compiler warning.' -r11 --revprop property 'svn:log' set on repository revision '11' $

Обратите внимание на то, что изменение этих неверсионированных свойств должно быть явно разрешено администратором (см. «Hook Scripts»). Учитывая то, что свойства не версионируются, при не аккуратном редактировании, вы рискуете потерять информацию. Для исключения потери информации, администратор хранилища может принять меры предосторожности и по умолчанию, изменение неверсионированных свойств запрещено.

Так же как и в случае с содержимым файлов, изменение свойств является локальной модификацией и становится постоянной при ее фиксации в хранилище с помощью svn commit. Изменение свойств можно легко отменить — команда svn revert восстановит файлы и директории до их первоначального состояния, включая содержимое, свойства и все остальное. Кроме того, интересную информацию о состоянии свойств файлов и директорий можно получить с помощью команд svn status и svn diff.

$ svn status calc/button.c M calc/button.c $ svn diff calc/button.c Property changes on: calc/button.c ___________________________________________________________________ Name: copyright + (c) 2003 Red-Bean Software $

Обратите внимание на то, что подкоманда status показывает M не в первой, а во второй колонке. Это потому, что в calc/button.c изменились свойства, а текстовое содержимое нет. Если бы мы изменили и то и другое, в первой колонке то же была бы буква M (см. «svn status»).

Конфликты свойств

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

% svn update calc M calc/Makefile.in C calc/button.c Updated to revision 143. $

В директории с конфликтующим элементом Subversion создает файл с расширением .prej, с подробностями о конфликте. Для разрешения конфликта необходимо познакомиться с содержимым этого файла. Пока не будет решен конфликт, во второй колонке вывода команды svn status будет присутствовать буква C, а попытки фиксации локальных изменений будут отклоняться.

$ svn status calc C calc/button.c ? calc/button.c.prej $ cat calc/button.c.prej prop 'linecount': user set to '1256', but update set to '1301'. $

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

Кроме того нужно помнить о нестандартном подходе, используемом Subversion при выводе различий для свойств. Безусловно, можно запустить svn diff перенправить вывод, для создания работоспособного файла отличий. Програма patch будет просто игнорировать различия свойств — как правило, она игнорирует любой мусор, который неможет обработать. К сожалению, это значит, что для полного применения отличий, сгенерированных svn diff, изменения свойств нужно вносить в ручную.

Как видите, наличие измененных свойств никак не отражается на привычном рабочем цикле. Операции обновления рабочей копии, проверки статуса файлов и директорий, вывод сообщений о сделанных изменениях и фиксация этих измениий в хранилище никак не зависят от наличия или отсутствия свойств. У svn просто имеется несколько дополнительных подкоманд для внесения изменений в свойства однако это просто достойное внимания отличие.



Использование веток


К этому моменту вы должны понимать как в хранилище, при каждой фиксации, создается полностью новое дерево файлов (называемое «правка»). Если нет, то вернитесь назад и прочитайте раздел «Правки».

Для этой главы, мы воспользуемся тем же примером, что и в Главе 2. Как вы помните, вы и ваш соразработчик Салли делите хранилище, содержащее два проекта, paint и calc. Как показывает Рисунок 4.2, «Начальная структура хранилища» каждая директория проекта содержит поддиректории с названиями trunk и branches. Назначение этих директорий скоро станет понятно.

Рисунок 4.2. Начальная структура хранилища

Как и раньше, будем считать что Салли и вы, оба, имеете рабочие копии проекта «calc». А конкретно, каждый из вас имеет рабочую копию /calc/trunk. Все файлы относящиеся к проекту находятся в этой поддиректории, а не прямо в /calc, потому, что ваша команда решила размещать главную линию разработки в /calc/trunk.

Скажем, перед вами была поставлена задача коренной реорганизации проекта. Это займет много времени и затронет все файлы проекта. Проблема заключается в том, что вы не хотите мешать Салли, которая прямо сейчас занимается исправлением небольших ошибок. Ее работа зависит от постоянной доступности последней версии проекта (директории /calc/trunk). Если вы начнете пошагово фиксировать свои изменения, вы конечно же смешаете Салли все карты.

Одним из вариантов является ограничение свободы действий: вы и Салли перестаете делиться информацией на неделю или две. В это время начинайте переворачивать и реорганизовывать файлы рабочей копии, но не фиксируйте и не обновляйте ее пока не закончите эту задачу. Однако в этом случае появляется несколько проблем. Во-первых это не очень надежно. Большинство людей предпочитают часто сохранять свою работу в хранилище, на случай если вдруг что-то плохое случится с рабочей копией. Во-вторых, это не достаточно гибко. Если вы работаете на разных компьютерах (к примеру если рабочая копия /calc/trunk есть у вас на разных машинах), вам придется вручную копировать изменения взад и вперед, либо делать всю работу на одном компьютере. А с другой стороны, вам трудно разделять вносимые изменения с кем-то еще. Общий при разработке программного обеспечения «лучший метод организации» это возможность совместного просмотра проделанной работы по мере продвижения. Если никто не видит ваших промежуточных фиксаций, вы теряете потенциальную возможность обратной связи. В конце концов, когда вы закончите свои изменения, вы можете обнаружить, что очень трудно заново слить сделанную вами работу с остальным программным кодом компании. Салли или (кто-то другой) могли внести изменения в хранилище, которые будет трудно внедрить в вашу рабочую копию — особенно если вы выполните svn update после нескольких недель изоляции.

Лучшим решением является создание вашей собственной ветки, или направления разработки, в хранилище. Это позволит вам часто сохранять наполовину поломанную работу не пересекаясь с другими, и кроме того, вы можете выборочно разделять информацию с другими соразработчиками. Дальше по тексту вы увидите как все это работает.



История Subversion


В начале 2000 года компания CollabNet, Inc. (http://www.collab.net) решила начать разработку программного обеспечения, призванного прийти на смену CVS, и стала искать людей, способных решить эту задачу. CollabNet предлагает комплекс программных средств для совместной работы, известный под названием CollabNet Enterprise Edition (CEE) [5], одним из компонентов которого является средство для управления версиями. В качестве такого средства в CEE использовалась CVS, хотя её недостатки были очевидны с самого начала, и для CollabNet было ясно, что рано или поздно придётся искать замену. К сожалению, CVS стала стандартом де-факто в мире программного обеспечения с открытым исходным кодом, главным образом потому, что ничего лучшего в то время не существовало, по крайней мере среди программ со свободной лицензией. И тогда CollabNet решила написать новую систему управления версиями с нуля, сохранив основные идеи CVS, но без ошибок и неудобств, присущих CVS.

В феврале 2000 года CollabNet связалась с автором книги Open Source Development with CVS[6] Карлом Фогелем [Karl Fogel] и предложила ему принять участие в этом новом проекте. Интересно, что Карл тогда уже обсуждал проект новой системы управления версиями со своим другом Джимом Блэнди [Jim Blandy]. Ещё в 1995 году они создали компанию Cyclic Software, которая занималась поддержкой пользователей CVS, и хотя позднее этот бизнес был продан, друзья продолжали использовать CVS в повседневной работе. Их разочарование в CVS заставило Джима серьёзно задуматься о том, как организовать управление версиями лучше, и он не только придумал название «Subversion», но и разработал основные принципы устройства хранилища Subversion. Карл немедленно согласился на предложение CollabNet, а работодатель Джима, RedHat Software, пожертвовал своим сотрудником для этого проекта, предоставив ему возможность работать над Subversion в течение неограниченного времени. CollabNet взяла на работу Карла и Бена Коллинза-Сассмана [Ben Collins-Sussman], и в мае началась работа по проектированию системы. В результате нескольких безошибочных шагов, предпринятых Брайаном Белендорфом [Brian Behlendorf] и Джейсоном Роббинсом [Jason Robbins] из CollabNet и Грегом Стайном, на тот момент независимым разработчиком, активно участвующим в создании спецификации WebDAV/DeltaV, вокруг Subversion быстро образовалось сообщество активных разработчиков. Оказалось, что многие люди испытывали похожее чувство разочарования от CVS, и они с радостью приветствовали появившуюся наконец возможность изменить положение вещей.

Команда первых инженеров решила остановиться на достижении ряда простых целей. Они не собирались изобретать велосипед в подходах к управлению версиями, скорее им просто хотелось исправить CVS. Эта команда решила, что Subversion должна соответствовать CVS по набору возможностей, сохранив ту же самую модель разработки, но без очевидных недостатков CVS. Хотя перед ними не стояла задача сделать систему, полностью идентичную CVS, было ясно, что они должны быть достаточно похожи друг на друга, чтобы любой пользователь CVS мог перейти на новую систему без особых затруднений.

И вот, 31 августа 2001 года, спустя четырнадцать месяцев с начала работы, команда прекратила использовать CVS и перешла на Subversion для управления версиями собственного исходного кода — Subversion стала «самодостаточной».

Хотя CollabNet стоит у истоков проекта и продолжает финансировать основную часть работы, оплачивая полный рабочий день нескольких ведущих разработчиков, Subversion развивается подобно большинству проектов разработки программного обеспечения с открытым исходным кодом, управляясь свободным и прозрачным набором правил, поощряющих меритократию. Лицензия CollabNet полностью соответствует принципам свободного программного обеспечения Debian — любой человек свободен устанавливать, изменять и распространять Subversion так, как ему заблагорассудится; для этого не требуется разрешение от CollabNet или кого-либо ещё.


[5] Кроме того, еще существует CollabNet Team Edition (CTE), предназначенный главным образом для небольших групп разработчиков.

[6] «Разработка программного обеспечения с открытым исходным кодом с помощью CVS»

Пред. Уровень выше След.
Глава 1. Введение Содержание Возможности Subversion


Изменяет


Рабочую копию



Ничего не меняет




Ничего не меняет




Создает рабочую копию.




Рабочую копию.




Как рабочую копию, так и хранилище




Хранилище, если копия задается через URL

Рабочая копия, если копия создается внутри неё.



Эта книга распространяется свободно


Эта книга начиналась с фрагментов документации, написанных разработчиками проекта Subversion, которые затем были собраны в единое целое и отредактированы. Поэтому, она всегда будет распространяться на условиях свободной лицензии (см. Приложение D, Copyright.) Фактически, книга писалась у всех на виду, как часть Subversion, что означает две вещи:

Вы всегда можете найти самую последнюю версию книги в хранилище Subversion, созданном специально для неё.

Вы можете распространять эту книгу и вносить в неё изменения по своему усмотрению — лицензия на использование книги является свободной. Конечно, будет лучше всего, если вместо того, чтобы распространять собственную версию книги, вы поделитесь отзывами и исправлениями с сообществом разработчиков Subversion. О том, как стать участником сообщества, написано в одном из разделов этой книги, см. «Contributing to Subversion».

Относительно свежую версию этой книги можно взять в Интернете по адресу http://svnbook.red-bean.com.

Пред. Уровень выше След.
Структура книги Содержание Благодарности


Join the Community


The first step in community participation is to find a way to stay on top of the latest happenings. To do this most effectively, you will want to subscribe to the main developer discussion list (<dev@subversion.tigris.org>) and commit mail list (<svn@subversion.tigris.org>). By following these lists even loosely, you will have access to important design discussions, be able to see actual changes to Subversion source code as they occur, and be able to witness peer reviews of those changes and proposed changes. These email based discussion lists are the primary communication media for Subversion development. See the Mailing Lists section of the website for other Subversion-related lists you might be interested in.

But how do you know what needs to be done? It is quite common for a programmer to have the greatest intentions of helping out with the development, yet be unable to find a good starting point. After all, not many folks come to the community having already decided on a particular itch they would like to scratch. But by watching the developer discussion lists, you might see mentions of existing bugs or feature requests fly by that particularly interest you. Also, a great place to look for outstanding, unclaimed tasks is the Issue Tracking database on the Subversion website. There you will find the current list of known bugs and feature requests. If you want to start with something small, look for issues marked as «bite-sized».



Как читать эту книгу?


Книга предназначена для людей с самым разным уровнем подготовки — от новичков, не имевших дела с управлением версиями ранее, до опытных системных администраторов. Важность той или иной главы для читателя будет зависеть от уровня его подготовки. Приведём наши рекомендации для разных групп читателей:

Опытные системные администраторы

Предполагается, что читатели этой группы раннее уже использовали CVS и теперь им не терпится поднять сервер Subversion как можно скорее. В Глава 5, Администрирование хранилища и Глава 6, Настройка сервера показано, как создать первое хранилище и сделать его доступным в сети. Далее можно перейти к изучению клиента Subversion, причём для пользователей CVS наиболее быстрым путём к цели будет чтение Глава 3, Экскурсия по Subversion и Приложение A, Subversion для пользователей CVS.

Новички

По-видимому, администратор уже установил Subversion в сети и вам необходимо научиться пользоваться клиентом. Если вы раньше не использовали систему управления версиями (например, CVS), то начать следует с Глава 2, Основные понятия и Глава 3, Экскурсия по Subversion, где содержатся основные вводные сведения. Если же вы хорошо знакомы с CVS, то вам больше подойдёт изучение главы 3 и приложения A.

Продвинутые пользователи

Рано или поздно ваш проект будет разрастаться, и тогда, независимо от того, администратор вы или пользователь, вам потребуется узнать, как делать в Subversion более сложные вещи: использовать ветки и осуществлять слияния (Глава 4, Ветвление и слияние), работать со свойствами, настраивать рабочую среду (Глава 7, Профессиональное использование Subversion) и т.д. Эти главы не являются важными в самом начале работы, но их следует прочесть, когда вы разберётесь с основами.

Разработчики

Предполагается, что вы уже знакомы с Subversion и хотите либо расширить её, либо создать новое программное обеспечение на основе её многочисленных API[2]. Что ж, Глава 8, Информация для разработчиков написана именно для вас.

Книга завершается справочным материалом — Глава 9, Полное справочное руководство по Subversion представляет собой справочное руководство по всем командам Subversion, а несколько полезных тем раскрыто в приложениях. К этим разделам вы скорее всего будете обращаться уже после прочтения книги.


[2] Application Program Interface, интерфейс прикладного программирования

Пред. Уровень выше След.
Об этой книге Содержание Соглашения, принятые в книге


Как рабочие копии отслеживают хранилище


В служебном каталоге .svn/ для каждого файла рабочего каталога Subversion записывает информацию о двух важнейших свойствах:

на какой правке основан ваш рабочий файл (это называется рабочая правка файла), и

временной (ударение на последний слог) метке, определяющей, когда рабочая копия последний раз обновлялась из хранилища.

Используя эту информацию при соединении с хранилищем, Subversion может сказать, в каком из следующих четырех состояний находится рабочий файл:

Не изменялся и не устарел

Файл не изменялся в рабочем каталоге, в хранилище не фиксировались изменения этого файла со времени создания его рабочей правки. Команды svn commit и svn update никаких операций делать не будут.

Изменялся локально и не устарел

Файл был изменен в рабочей копии, но в хранилище не фиксировались изменения этого файла после правки, на которой он основан. Есть локальные изменения, которые не были зафиксированы в хранилище, поэтому svn commit выполнит фиксацию ваших изменений, а svn update не сделает ничего.

Не изменялся и устарел

В рабочем каталоге файл не изменялся, но был изменен в хранилище. Необходимо выполнить обновление файла для того, чтобы он соответствовал текущей правке. Команда svn commit не сделает ничего, а svn update обновит вашу рабочую копию файла в соответствии с последними изменениями.

Изменялся локально и устарел

Файл был изменен как в рабочем каталоге, так и в хранилище. svn commit потерпит неудачу, выдав ошибку «out-of-date». Файл необходимо сначала обновить; svn update попытается объединить локальные изменения с опубликованными. Если Subversion не сможет самостоятельно совершить объединение, он предложит пользователю разрешить конфликт вручную.

Может показаться, что следить за актуальным состоянием рабочей копии сложно. Это не так. Для того, чтобы узнать состояние любого элемента в вашей рабочей копии существует команда svn status. За более подробной информацией об этой команде обратитесь к «svn status».



Клиент командной строки Subversion: svn


Для того что бы воспользоваться клиентом, введите svn, и желаемую подкоманду [54], а так же любые другие параметры командной строки или указатели на объекты которые хотите задействовать. Не существует порядка в котором подкоманды и параметры должны быть использованы. Например, всё нижеприведённое есть правильное использование svn status:

$ svn -v status $ svn status -v $ svn status -v myfile

Много примеров использования большинства клиентских команд может быть найдено в главе Глава 3, Экскурсия по Subversion. Команды для управления свойствами описаны в главе «Свойства».