3 "Project-Id-Version: PACKAGE VERSION\n"
4 "POT-Creation-Date: 2007-11-12 02:25 +0000\n"
5 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
6 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
7 "Language-Team: LANGUAGE <LL@li.org>\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
10 "Content-Transfer-Encoding: 8bit\n"
12 #. When image changes, this message will be marked fuzzy or untranslated for you.
13 #. It doesn't matter what you translate it to: it's not used at all.
15 #: ../source/book.xml:956
16 msgid "@@image: 'images/ch01dia1.png'; md5=d5cf54020bcbb99fb12150481d94bffa"
19 #. When image changes, this message will be marked fuzzy or untranslated for you.
20 #. It doesn't matter what you translate it to: it's not used at all.
22 #: ../source/book.xml:1086
23 msgid "@@image: 'images/ch02dia1.png'; md5=9f98bd2bd15fabc36d55db0572a7b32b"
26 #. When image changes, this message will be marked fuzzy or untranslated for you.
27 #. It doesn't matter what you translate it to: it's not used at all.
29 #: ../source/book.xml:1157
30 msgid "@@image: 'images/ch02dia2.png'; md5=4c3e6e55f9a0c50d6925f5ca4587e47b"
33 #. When image changes, this message will be marked fuzzy or untranslated for you.
34 #. It doesn't matter what you translate it to: it's not used at all.
36 #: ../source/book.xml:1186
37 msgid "@@image: 'images/ch02dia3.png'; md5=e9cd778666a999ab329a069efed37500"
40 #. When image changes, this message will be marked fuzzy or untranslated for you.
41 #. It doesn't matter what you translate it to: it's not used at all.
43 #: ../source/book.xml:1271
44 msgid "@@image: 'images/ch02dia4.png'; md5=8d13576c2af1db88349f6ff144ef6fc2"
47 #. When image changes, this message will be marked fuzzy or untranslated for you.
48 #. It doesn't matter what you translate it to: it's not used at all.
50 #: ../source/book.xml:1281
51 msgid "@@image: 'images/ch02dia5.png'; md5=f4ec352cd843cf130fe500cfdbc358ca"
54 #. When image changes, this message will be marked fuzzy or untranslated for you.
55 #. It doesn't matter what you translate it to: it's not used at all.
57 #: ../source/book.xml:1469
58 msgid "@@image: 'images/ch02dia6.png'; md5=d4eac305c63464419d945a616284c4ce"
61 #. When image changes, this message will be marked fuzzy or untranslated for you.
62 #. It doesn't matter what you translate it to: it's not used at all.
64 #: ../source/book.xml:1652
65 msgid "@@image: 'images/ch02dia7.png'; md5=067bb47f6fe3dcdeefac6755da876cdf"
68 #. When image changes, this message will be marked fuzzy or untranslated for you.
69 #. It doesn't matter what you translate it to: it's not used at all.
71 #: ../source/book.xml:6672
72 msgid "@@image: 'images/ch04dia1.png'; md5=a157a2c9fc737cab3db918aaf489bf7e"
75 #. When image changes, this message will be marked fuzzy or untranslated for you.
76 #. It doesn't matter what you translate it to: it's not used at all.
78 #: ../source/book.xml:6710
79 msgid "@@image: 'images/ch04dia2.png'; md5=5c6b571282ff05d99a99d69fdef50378"
82 #. When image changes, this message will be marked fuzzy or untranslated for you.
83 #. It doesn't matter what you translate it to: it's not used at all.
85 #: ../source/book.xml:6855
86 msgid "@@image: 'images/ch04dia3.png'; md5=7226def64bf6dea42b547d968b853a08"
89 #. When image changes, this message will be marked fuzzy or untranslated for you.
90 #. It doesn't matter what you translate it to: it's not used at all.
92 #: ../source/book.xml:6945
93 msgid "@@image: 'images/ch04dia4.png'; md5=03cbad24eee5abe0cadc452be19c2613"
96 #. When image changes, this message will be marked fuzzy or untranslated for you.
97 #. It doesn't matter what you translate it to: it's not used at all.
99 #: ../source/book.xml:15551
100 msgid "@@image: 'images/ch08dia1.png'; md5=870a5b07012b21f7b187fdb1d912d8d6"
103 #. When image changes, this message will be marked fuzzy or untranslated for you.
104 #. It doesn't matter what you translate it to: it's not used at all.
106 #: ../source/book.xml:15580
107 msgid "@@image: 'images/ch08dia2.png'; md5=a72633f0cc8f6f83fa4d8a96b47202ca"
111 #: ../source/book.xml:4
112 msgid "Version Control with Subversion"
116 #: ../source/book.xml:5
117 msgid "For Subversion 1.5(Compiled from r2881)"
121 #: ../source/book.xml:6
126 #: ../source/book.xml:7
127 msgid "?-?????-???-?"
131 #: ../source/book.xml:11
136 #: ../source/book.xml:12
137 msgid "Collins-Sussman"
141 #: ../source/book.xml:17
146 #: ../source/book.xml:18
151 #: ../source/book.xml:23
156 #: ../source/book.xml:24
161 #: ../source/book.xml:30
166 #: ../source/book.xml:31
171 #: ../source/book.xml:34
172 msgid "350 pages (est.)"
176 #: ../source/book.xml:35
181 #: ../source/book.xml:37
186 #: ../source/book.xml:38
191 #: ../source/book.xml:39
196 #: ../source/book.xml:40
201 #: ../source/book.xml:41
206 #: ../source/book.xml:42
211 #: ../source/book.xml:43
212 msgid "Ben Collins-Sussman"
216 #: ../source/book.xml:44
217 msgid "Brian W. Fitzpatrick"
221 #: ../source/book.xml:45
222 msgid "C. Michael Pilato"
226 #: ../source/book.xml:48
227 msgid "This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit <uri href=\"http://creativecommons.org/licenses/by/2.0/\">http://creativecommons.org/licenses/by/2.0/</uri> or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA."
231 #: ../source/book.xml:62
236 #: ../source/book.xml:65
241 #: ../source/book.xml:66
246 #: ../source/book.xml:69
247 msgid "Chicago, March 14, 2004"
251 #: ../source/book.xml:71
252 msgid "A bad Frequently Asked Questions (FAQ) sheet is one that is composed not of the questions people actually asked, but of the questions the FAQ's author <emphasis>wished</emphasis> people had asked. Perhaps you've seen the type before:"
256 #: ../source/book.xml:76
257 msgid "Q: How can I use Glorbosoft XYZ to maximize team productivity?"
261 #: ../source/book.xml:80
262 msgid "A: Many of our customers want to know how they can maximize productivity through our patented office groupware innovations. The answer is simple: first, click on the <quote><literal>File</literal></quote> menu, scroll down to <quote><literal>Increase Productivity</literal></quote>, then…"
266 #: ../source/book.xml:87
267 msgid "The problem with such FAQs is that they are not, in a literal sense, FAQs at all. No one ever called the tech support line and asked, <quote>How can we maximize productivity?</quote>. Rather, people asked highly specific questions, like, <quote>How can we change the calendaring system to send reminders two days in advance instead of one?</quote> and so on. But it's a lot easier to make up imaginary Frequently Asked Questions than it is to discover the real ones. Compiling a true FAQ sheet requires a sustained, organized effort: over the lifetime of the software, incoming questions must be tracked, responses monitored, and all gathered into a coherent, searchable whole that reflects the collective experience of users in the wild. It calls for the patient, observant attitude of a field naturalist. No grand hypothesizing, no visionary pronouncements here—open eyes and accurate note-taking are what's needed most."
271 #: ../source/book.xml:103
272 msgid "What I love about this book is that it grew out of just such a process, and shows it on every page. It is the direct result of the authors' encounters with users. It began with Ben Collins-Sussman's observation that people were asking the same basic questions over and over on the Subversion mailing lists: What are the standard workflows to use with Subversion? Do branches and tags work the same way as in other version control systems? How can I find out who made a particular change?"
276 #: ../source/book.xml:111
277 msgid "Frustrated at seeing the same questions day after day, Ben worked intensely over a month in the summer of 2002 to write <citetitle>The Subversion Handbook</citetitle>, a sixty page manual that covered all the basics of using Subversion. The manual made no pretense of being complete, but it was distributed with Subversion and got users over that initial hump in the learning curve. When O'Reilly and Associates decided to publish a full-length Subversion book, the path of least resistance was obvious: just expand the Subversion handbook."
281 #: ../source/book.xml:121
282 msgid "The three co-authors of the new book were thus presented with an unusual opportunity. Officially, their task was to write a book top-down, starting from a table of contents and an initial draft. But they also had access to a steady stream—indeed, an uncontrollable geyser—of bottom-up source material. Subversion was already in the hands of thousands of early adopters, and those users were giving tons of feedback, not only about Subversion, but about its existing documentation."
286 #: ../source/book.xml:130
287 msgid "During the entire time they wrote this book, Ben, Mike, and Brian haunted the Subversion mailing lists and chat rooms incessantly, carefully noting the problems users were having in real-life situations. Monitoring such feedback was part of their job descriptions at CollabNet anyway, and it gave them a huge advantage when they set out to document Subversion. The book they produced is grounded firmly in the bedrock of experience, not in the shifting sands of wishful thinking; it combines the best aspects of user manual and FAQ sheet. This duality might not be noticeable on a first reading. Taken in order, front to back, the book is simply a straightforward description of a piece of software. There's the overview, the obligatory guided tour, the chapter on administrative configuration, some advanced topics, and of course a command reference and troubleshooting guide. Only when you come back to it later, seeking the solution to some specific problem, does its authenticity shine out: the telling details that can only result from encounters with the unexpected, the examples honed from genuine use cases, and most of all the sensitivity to the user's needs and the user's point of view."
291 #: ../source/book.xml:150
292 msgid "Of course, no one can promise that this book will answer every question you have about Subversion. Sometimes, the precision with which it anticipates your questions will seem eerily telepathic; yet occasionally, you will stumble into a hole in the community's knowledge, and come away empty-handed. When this happens, the best thing you can do is email <email>users@subversion.tigris.org</email> and present your problem. The authors are still there, still watching, and they include not just the three listed on the cover, but many others who contributed corrections and original material. From the community's point of view, solving your problem is merely a pleasant side effect of a much larger project—namely, slowly adjusting this book, and ultimately Subversion itself, to more closely match the way people actually use it. They are eager to hear from you not merely because they can help you, but because you can help them. With Subversion as with all active free software projects, <emphasis>you are not alone</emphasis>."
296 #: ../source/book.xml:168
297 msgid "Let this book be your first companion."
301 #: ../source/book.xml:177
306 #: ../source/book.xml:180
311 #: ../source/book.xml:182
312 msgid "It is important not to let the perfect become the enemy of the good, even when you can agree on what perfect is. Doubly so when you can't. As unpleasant as it is to be trapped by past mistakes, you can't make any progress by being afraid of your own shadow during design."
316 #: ../source/book.xml:189
317 msgid "<indexterm><primary>Concurrent Versions System (CVS)</primary></indexterm> In the world of open-source software, the Concurrent Versions System (CVS) was the tool of choice for version control for many years. And rightly so. CVS was open-source software itself, and its non-restrictive modus operandi and support for networked operation allowed dozens of geographically dispersed programmers to share their work. It fit the collaborative nature of the open-source world very well. CVS and its semi-chaotic development model have since become cornerstones of open-source culture."
321 #: ../source/book.xml:200
322 msgid "But CVS was not without its flaws, and simply fixing those flaws promised to be an enormous effort. Enter Subversion. Designed to be a successor to CVS, Subversion's originators set out to win the hearts of CVS users in two ways—by creating an open-source system with a design (and <quote>look and feel</quote>) similar to CVS, and by attempting to avoid most of CVS's noticeable flaws. While the result isn't necessarily the next great evolution in version control design, Subversion <emphasis>is</emphasis> very powerful, very usable, and very flexible. And for the most part, almost all newly-started open-source projects now choose Subversion instead of CVS."
326 #: ../source/book.xml:211
327 msgid "This book is written to document the 1.5 series of the Subversion version control system. We have made every attempt to be thorough in our coverage. However, Subversion has a thriving and energetic development community, so there are already a number of features and improvements planned for future versions of Subversion that may change some of the commands and specific notes in this book."
331 #: ../source/book.xml:223
336 #: ../source/book.xml:225
337 msgid "This book is written for computer-literate folk who want to use Subversion to manage their data. While Subversion runs on a number of different operating systems, its primary user interface is command-line based. That command-line tool (<command>svn</command>), and some auxiliary programs, are the focus of this book."
341 #: ../source/book.xml:231
342 msgid "For consistency, the examples in this book assume the reader is using a Unix-like operating system and is relatively comfortable with Unix and command-line interfaces. That said, the <command>svn</command> program also runs on non-Unix platforms like Microsoft Windows. With a few minor exceptions, such as the use of backward slashes (<literal>\\</literal>) instead of forward slashes (<literal>/</literal>) for path separators, the input to and output from this tool when run on Windows are identical to its Unix counterpart."
346 #: ../source/book.xml:240
347 msgid "Most readers are probably programmers or system administrators who need to track changes to source code. This is the most common use for Subversion, and therefore it is the scenario underlying all of the book's examples. But Subversion can be used to manage changes to any sort of information—images, music, databases, documentation, and so on. To Subversion, all data is just data."
351 #: ../source/book.xml:247
352 msgid "While this book is written with the assumption that the reader has never used a version control system, we've also tried to make it easy for users of CVS (and other systems) to make a painless leap into Subversion. Special sidebars may mention other version control systems from time to time, and a special appendix summarizes many of the differences between CVS and Subversion."
356 #: ../source/book.xml:254
357 msgid "Note also that the source code examples used throughout the book are only examples. While they will compile with the proper compiler incantations, they are intended to illustrate a particular scenario, not necessarily serve as examples of good programming style or practices."
361 #: ../source/book.xml:265
362 msgid "How to Read this Book"
366 #: ../source/book.xml:267
367 msgid "Technical books always face a certain dilemma: whether to cater to <firstterm>top-down</firstterm> or <firstterm>bottom-up</firstterm> learners. A top-down learner prefers to read or skim documentation, getting a large overview of how the system works; only then does she actually start using the software. A bottom-learner is a <quote>learn by doing</quote> person, someone who just wants to dive into the software and figure it out as she goes, referring to book sections when necessary. Most books tend to be written for one type of person or the other, and this book is undoubtedly biased towards top-down learners. (And if you're actually reading this section, you're probably already a top-down learner yourself!) However, if you're a bottom-up person, don't despair. While the book may be laid out as a broad survey of Subversion topics, the contents of each section tends to be heavy with specific examples that you can try-by-doing. For the impatient folks who just want to get going, you can jump right to <xref linkend=\"svn.intro\"/>."
371 #: ../source/book.xml:285
372 msgid "Regardless of your learning style, this book aims to be useful to people of widely different backgrounds—from people with no previous experience in version control to experienced system administrators. Depending on your own background, certain chapters may be more or less important to you. The following can be considered a <quote>recommended reading list</quote> for various types of readers:"
376 #: ../source/book.xml:295
377 msgid "Experienced System Administrators"
381 #: ../source/book.xml:297
382 msgid "The assumption here is that you've probably used version control before before, and are dying to get a Subversion server up and running ASAP. <xref linkend=\"svn.reposadmin\"/> and <xref linkend=\"svn.serverconfig\"/> will show you how to create your first repository and make it available over the network. After that's done, <xref linkend=\"svn.tour\"/> and <xref linkend=\"svn.forcvs\"/> are the fastest routes to learning the Subversion client."
386 #: ../source/book.xml:310
391 #: ../source/book.xml:312
392 msgid "Your administrator has probably set up Subversion already, and you need to learn how to use the client. If you've never used a version control system, then <xref linkend=\"svn.basic\"/> is a vital introduction to the ideas behind version control. <xref linkend=\"svn.tour\"/> is a guided tour of the Subversion client."
396 #: ../source/book.xml:321
397 msgid "Advanced users"
401 #: ../source/book.xml:323
402 msgid "Whether you're a user or administrator, eventually your project will grow larger. You're going to want to learn how to do more advanced things with Subversion, such as how to use branches and perform merges (<xref linkend=\"svn.branchmerge\"/>), how to use Subversion's property support (<xref linkend=\"svn.advanced\"/>), how to configure runtime options (<xref linkend=\"svn.customization\"/>), and other things. These chapters aren't critical at first, but be sure to read them once you're comfortable with the basics."
406 #: ../source/book.xml:334
411 #: ../source/book.xml:336
412 msgid "Presumably, you're already familiar with Subversion, and now want to either extend it or build new software on top of its many APIs. <xref linkend=\"svn.developer\"/> is just for you."
416 #: ../source/book.xml:343
417 msgid "The book ends with reference material—<xref linkend=\"svn.ref\"/> is a reference guide for all Subversion commands, and the appendices cover a number of useful topics. These are the chapters you're mostly likely to come back to after you've finished the book."
421 #: ../source/book.xml:353
422 msgid "Conventions Used in This Book"
426 #: ../source/book.xml:355
427 msgid "This section covers the various conventions used in this book."
431 #: ../source/book.xml:360
432 msgid "Typographic Conventions"
436 #: ../source/book.xml:365
437 msgid "Constant width"
441 #: ../source/book.xml:368
442 msgid "Used for commands, command output, and options"
446 #: ../source/book.xml:373
447 msgid "Constant width italic"
451 #: ../source/book.xml:376
452 msgid "Used for replaceable items in code and text"
456 #: ../source/book.xml:381
461 #: ../source/book.xml:384
462 msgid "Used for file and directory names"
466 #: ../source/book.xml:392
471 #: ../source/book.xml:395
472 msgid "This icon designates a note relating to the surrounding text."
476 #: ../source/book.xml:399
477 msgid "This icon designates a helpful tip relating to the surrounding text."
481 #: ../source/book.xml:403
482 msgid "This icon designates a warning relating to the surrounding text."
486 #: ../source/book.xml:413
487 msgid "Organization of This Book"
491 #: ../source/book.xml:415
492 msgid "The chapters that follow and their contents are listed here:"
496 #: ../source/book.xml:423
497 msgid "Covers the history of Subversion as well as its features, architecture, and components."
501 #: ../source/book.xml:432
502 msgid "Explains the basics of version control and different versioning models, along with Subversion's repository, working copies, and revisions."
506 #: ../source/book.xml:442
507 msgid "Walks you through a day in the life of a Subversion user. It demonstrates how to use a Subversion client to obtain, modify, and commit data."
511 #: ../source/book.xml:452
512 msgid "Covers more complex features that regular users will eventually come into contact with, such as versioned metadata, file locking, and peg revisions."
516 #: ../source/book.xml:462
517 msgid "Discusses branches, merges, and tagging, including best practices for branching and merging, common use cases, how to undo changes, and how to easily swing from one branch to the next."
521 #: ../source/book.xml:473
522 msgid "Describes the basics of the Subversion repository, how to create, configure, and maintain a repository, and the tools you can use to do all of this."
526 #: ../source/book.xml:483
527 msgid "Explains how to configure your Subversion server and different ways to access your repository: <literal>HTTP</literal>, the <literal>svn</literal> protocol, and local disk access. It also covers the details of authentication, authorization and anonymous access."
531 #: ../source/book.xml:496
532 msgid "Explores the Subversion client configuration files, the handling of internationalized text, and how to make external tools cooperate with Subversion."
536 #: ../source/book.xml:506
537 msgid "Describes the internals of Subversion, the Subversion filesystem, and the working copy administrative areas from a programmer's point of view. Demonstrates how to use the public APIs to write a program that uses Subversion, and most importantly, how to contribute to the development of Subversion."
541 #: ../source/book.xml:519
542 msgid "Explains in great detail every subcommand of <command>svn</command>, <command>svnadmin</command>, and <command>svnlook</command> with plenty of examples for the whole family!"
546 #: ../source/book.xml:530
547 msgid "For the impatient, a whirlwind explanation of how to install Subversion and start using it immediately. You have been warned."
551 #: ../source/book.xml:540
552 msgid "Covers the similarities and differences between Subversion and CVS, with numerous suggestions on how to break all the bad habits you picked up from years of using CVS. Included are descriptions of Subversion revision numbers, versioned directories, offline operations, <command>update</command> vs. <command>status</command>, branches, tags, metadata, conflict resolution, and authentication."
556 #: ../source/book.xml:555
557 msgid "Describes the details of WebDAV and DeltaV, and how you can configure your Subversion repository to be mounted read/write as a DAV share."
561 #: ../source/book.xml:565
562 msgid "Discusses tools that support or use Subversion, including alternative client programs, repository browser tools, and so on."
566 #: ../source/book.xml:577
567 msgid "This Book is Free"
571 #: ../source/book.xml:579
572 msgid "This book started out as bits of documentation written by Subversion project developers, which were then coalesced into a single work and rewritten. As such, it has always been under a free license. (See <xref linkend=\"svn.copyright\"/>.) In fact, the book was written in the public eye, originally as a part of Subversion project itself. This means two things:"
576 #: ../source/book.xml:587
577 msgid "You will always find the latest version of this book in the book's own Subversion repository."
581 #: ../source/book.xml:591
582 msgid "You can make changes to this book and redistribute it however you wish—it's under a free license. Your only obligation is to maintain proper attribution to the original authors. Of course, rather than distribute your own private version of this book, we'd much rather you send feedback and patches to the Subversion developer community."
585 #. O'REILLY SHOULD TWEAK THIS PARAGRAPH
587 #: ../source/book.xml:600
588 msgid "The online home of this book's development and most of the volunteer-driven translation efforts around it is <uri href=\"http://svnbook.red-bean.com\">http://svnbook.red-bean.com</uri>. There, you can find links to the latest releases and tagged versions of the book in various formats, as well as instructions for accessing the book's Subversion repository (where lives its DocBook XML source code). Feedback is welcome—encouraged, even. Please submit all comments, complaints, and patches against the book sources to <email>svnbook-dev@red-bean.com</email>."
592 #: ../source/book.xml:615
593 msgid "Acknowledgments"
597 #: ../source/book.xml:623
598 msgid "Oh, and thanks, Karl, for being too overworked to write this book yourself."
602 #: ../source/book.xml:617
603 msgid "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.<placeholder-1/>"
607 #: ../source/book.xml:625
608 msgid "Thanks to O'Reilly and our editors, Linda Mui and Tatiana Diaz for their patience and support."
612 #: ../source/book.xml:627
613 msgid "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: David Anderson, 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, David Glasser, Matthew Gregan, Art Haas, Eric Hanchrow, 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, Christopher Ness, Mats Nilsson, Joe Orton, Amy Lyn Pilato, Kevin Pilch-Bisson, Dmitriy Popkov, Michael Price, Mark Proctor, Steffen Prohaska, Daniel Rall, Jack Repenning, 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."
617 #: ../source/book.xml:654
618 msgid "From Ben Collins-Sussman"
622 #: ../source/book.xml:656
623 msgid "Thanks to my wife Frances, who, for many months, got to hear, <quote>But honey, I'm still working on the book</quote>, rather than the usual, <quote>But honey, I'm still doing email.</quote> I don't know where she gets all that patience! She's my perfect counterbalance."
627 #: ../source/book.xml:661
628 msgid "Thanks to my extended family and friends for their sincere encouragement, despite having no actual interest in the subject. (You know, the ones who say, <quote>Ooh, you wrote a book?</quote>, and then when you tell them it's a computer book, sort of glaze over.)"
632 #: ../source/book.xml:666
633 msgid "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."
637 #: ../source/book.xml:668
638 msgid "Thanks to my parents for the perfect low-level formatting, and being unbelievable role models. Thanks to my son for the opportunity to pass that on."
642 #: ../source/book.xml:675
643 msgid "From Brian W. Fitzpatrick"
646 #. ### TODO(fitz): update this?
648 #: ../source/book.xml:678
649 msgid "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."
653 #: ../source/book.xml:685
654 msgid "To Mike and Ben: It was a pleasure working with you on the book. Heck, it's a pleasure working with you at work!"
658 #: ../source/book.xml:687
659 msgid "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."
663 #: ../source/book.xml:691
664 msgid "Lastly, thanks to my Grandfather who always told me that <quote>freedom equals responsibility.</quote> I couldn't agree more."
668 #: ../source/book.xml:698
669 msgid "From C. Michael Pilato"
673 #: ../source/book.xml:700
674 msgid "Special thanks to Amy, my best friend and wife of nine incredible years, for her love and patient support, for putting up with the late nights, and for graciously enduring the version control processes I've imposed on her. Don't worry, Sweetheart—you'll be a TortoiseSVN wizard in no time!"
678 #: ../source/book.xml:706
679 msgid "Gavin, there probably aren't many words in this book that you can successfully <quote>sound out</quote> at this stage, but when you've finally got a handle on the written form of this crazy language we speak, I hope you're as proud of your Daddy as he is of you."
683 #: ../source/book.xml:713
684 msgid "Translation: Daddy loves you and hopes you like computers as much as you like basketball, baseball, and football. (Wasn't that obvious?)"
688 #: ../source/book.xml:711
689 msgid "Aidan, Daddy luffoo et ope Aiduh yike contootoo as much as Aiduh yike batetball, base-ball, et bootball. <placeholder-1/>"
693 #: ../source/book.xml:717
694 msgid "Mom and Dad, thanks for your constant support and enthusiasm. Mom- and Dad-in-law, thanks for all of the same <emphasis>plus</emphasis> your fabulous daughter."
698 #: ../source/book.xml:720
699 msgid "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 <emphasis>are</emphasis> my <filename>.emacs</filename>; 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!"
703 #: ../source/book.xml:728
704 msgid "Finally, to the One who perfectly demonstrates creative excellence—thank You."
708 #: ../source/book.xml:737
709 msgid "What is Subversion?"
713 #: ../source/book.xml:739
714 msgid "Subversion is a free/open-source version control system. That is, Subversion manages files and directories, and the changes made to them, over time. This allows you to recover older versions of your data, or examine the history of how your data changed. In this regard, many people think of a version control system as a sort of <quote>time machine</quote>."
718 #: ../source/book.xml:745
719 msgid "Subversion can operate across networks, which allows it to be used by people on different computers. At some level, the ability for various people to modify and manage the same set of data from their respective locations fosters collaboration. Progress can occur more quickly without a single conduit through which all modifications must occur. And because the work is versioned, you need not fear that quality is the trade-off for losing that conduit—if some incorrect change is made to the data, just undo that change."
723 #: ../source/book.xml:754
724 msgid "Some version control systems are also software configuration management (SCM) systems. These systems are specifically tailored to manage trees of source code, and have many features that are specific to software development—such as natively understanding programming languages, or supplying tools for building software. Subversion, however, is not one of these systems. It is a general system that can be used to manage <emphasis>any</emphasis> collection of files. For you, those files might be source code—for others, anything from grocery shopping lists to digital video mixdowns and beyond."
728 #: ../source/book.xml:768
729 msgid "Subversion's History"
733 #: ../source/book.xml:770
734 msgid "<indexterm><primary>Subversion</primary><secondary>history of</secondary></indexterm> In early 2000, CollabNet, Inc. (<uri href=\"http://www.collab.net\">http://www.collab.net</uri>) began seeking developers to write a replacement for CVS. CollabNet offers a collaboration software suite called CollabNet Enterprise Edition (CEE) of which one component is version control. Although CEE used CVS as its initial version control system, CVS's limitations were obvious from the beginning, and CollabNet knew it would eventually have to find something better. Unfortunately, CVS had become the de facto standard in the open source world largely because there <emphasis>wasn't</emphasis> anything better, at least not under a free license. So CollabNet determined to write a new version control system from scratch, retaining the basic ideas of CVS, but without the bugs and misfeatures."
738 #: ../source/book.xml:785
739 msgid "In February 2000, they contacted Karl Fogel, the author of <citetitle>Open Source Development with CVS</citetitle> (Coriolis, 1999), and asked if he'd like to work on this new project. Coincidentally, at the time Karl was already discussing a design for a new version control system with his friend Jim Blandy. In 1995, the two had started Cyclic Software, a company providing CVS support contracts, and although they later sold the business, they still used CVS every day at their jobs. Their frustration with CVS had led Jim to think carefully about better ways to manage versioned data, and he'd already come up with not only the name <quote>Subversion</quote>, but also with the basic design of the Subversion data store. When CollabNet called, Karl immediately agreed to work on the project, and Jim got his employer, Red Hat Software, to essentially donate him to the project for an indefinite period of time. CollabNet hired Karl and Ben Collins-Sussman, and detailed design work began in May. With the help of some well-placed prods from Brian Behlendorf and Jason Robbins of CollabNet, and Greg Stein (at the time an independent developer active in the WebDAV/DeltaV specification process), Subversion quickly attracted a community of active developers. It turned out that many people had had the same frustrating experiences with CVS, and welcomed the chance to finally do something about it."
743 #: ../source/book.xml:809
744 msgid "The original design team settled on some simple goals. They didn't want to break new ground in version control methodology, they just wanted to fix CVS. They decided that Subversion would match CVS's features, and preserve the same development model, but not duplicate CVS's most obvious flaws. And although it did not need to be a drop-in replacement for CVS, it should be similar enough that any CVS user could make the switch with little effort."
748 #: ../source/book.xml:817
749 msgid "After fourteen months of coding, Subversion became <quote>self-hosting</quote> on August 31, 2001. That is, Subversion developers stopped using CVS to manage Subversion's own source code, and started using Subversion instead."
753 #: ../source/book.xml:821
754 msgid "While CollabNet started the project, and still funds a large chunk of the work (it pays the salaries of a few full-time Subversion developers), Subversion is run like most open-source projects, governed by a loose, transparent set of rules that encourage meritocracy. CollabNet's copyright license is fully compliant with the Debian Free Software Guidelines. In other words, anyone is free to download, modify, and redistribute Subversion as he pleases; no permission from CollabNet or anyone else is required."
758 #: ../source/book.xml:834
759 msgid "Subversion's Features"
763 #: ../source/book.xml:836
764 msgid "When discussing the features that Subversion brings to the version control table, it is often helpful to speak of them in terms of how they improve upon CVS's design. If you're not familiar with CVS, you may not understand all of these features. And if you're not familiar with version control at all, your eyes may glaze over unless you first read <xref linkend=\"svn.basic\"/>, in which we provide a gentle introduction to version control."
768 #: ../source/book.xml:843
769 msgid "Subversion provides:"
773 #: ../source/book.xml:846
774 msgid "Directory versioning"
778 #: ../source/book.xml:848
779 msgid "CVS only tracks the history of individual files, but Subversion implements a <quote>virtual</quote> versioned filesystem that tracks changes to whole directory trees over time. Files <emphasis>and</emphasis> directories are versioned."
783 #: ../source/book.xml:856
784 msgid "True version history"
788 #: ../source/book.xml:858
789 msgid "Since CVS is limited to file versioning, operations such as copies and renames—which might happen to files, but which are really changes to the contents of some containing directory—aren't supported in CVS. Additionally, in CVS you cannot replace a versioned file with some new thing of the same name without the new item inheriting the history of the old—perhaps completely unrelated—file. With Subversion, you can add, delete, copy, and rename both files and directories. And every newly added file begins with a fresh, clean history all its own."
793 #: ../source/book.xml:872
794 msgid "Atomic commits"
798 #: ../source/book.xml:874
799 msgid "A collection of modifications either goes into the repository completely, or not at all. This allows developers to construct and commit changes as logical chunks, and prevents problems that can occur when only a portion of a set of changes is successfully sent to the repository."
803 #: ../source/book.xml:883
804 msgid "Versioned metadata"
808 #: ../source/book.xml:885
809 msgid "Each file and directory has a set of properties—keys and their values—associated with it. You can create and store any arbitrary key/value pairs you wish. Properties are versioned over time, just like file contents."
813 #: ../source/book.xml:893
814 msgid "Choice of network layers"
818 #: ../source/book.xml:895
819 msgid "Subversion has an abstracted notion of repository access, making it easy for people to implement new network mechanisms. Subversion can plug into the Apache HTTP Server as an extension module. This gives Subversion a big advantage in stability and interoperability, and instant access to existing features provided by that server—authentication, authorization, wire compression, and so on. A more lightweight, standalone Subversion server process is also available. This server speaks a custom protocol which can be easily tunneled over SSH."
823 #: ../source/book.xml:909
824 msgid "Consistent data handling"
828 #: ../source/book.xml:911
829 msgid "Subversion expresses file differences using a binary differencing algorithm, which works identically on both text (human-readable) and binary (human-unreadable) files. Both types of files are stored equally compressed in the repository, and differences are transmitted in both directions across the network."
833 #: ../source/book.xml:920
834 msgid "Efficient branching and tagging"
838 #: ../source/book.xml:922
839 msgid "The cost of branching and tagging need not be proportional to the project size. Subversion creates branches and tags by simply copying the project, using a mechanism similar to a hard-link. Thus these operations take only a very small, constant amount of time."
843 #: ../source/book.xml:931
848 #: ../source/book.xml:933
849 msgid "Subversion has no historical baggage; it is implemented as a collection of shared C libraries with well-defined APIs. This makes Subversion extremely maintainable and usable by other applications and languages."
853 #: ../source/book.xml:945 ../source/book.xml:952
854 msgid "Subversion's Architecture"
858 #: ../source/book.xml:947
859 msgid "<xref linkend=\"svn.intro.architecture.dia-1\"/> illustrates a <quote>mile-high</quote> view of Subversion's design."
863 #: ../source/book.xml:960
864 msgid "On one end is a Subversion repository that holds all of your versioned data. On the other end is your Subversion client program, which manages local reflections of portions of that versioned data (called <quote>working copies</quote>). Between these extremes are multiple routes through various Repository Access (RA) layers. Some of these routes go across computer networks and through network servers which then access the repository. Others bypass the network altogether and access the repository directly."
868 #: ../source/book.xml:973
869 msgid "Subversion's Components"
873 #: ../source/book.xml:975
874 msgid "Subversion, once installed, has a number of different pieces. The following is a quick overview of what you get. Don't be alarmed if the brief descriptions leave you scratching your head—there are <emphasis>plenty</emphasis> more pages in this book devoted to alleviating that confusion."
878 #: ../source/book.xml:982 ../source/book.xml:17030 ../source/book.xml:17133 ../source/book.xml:17237 ../source/book.xml:17322 ../source/book.xml:17453 ../source/book.xml:17529 ../source/book.xml:17657 ../source/book.xml:17813 ../source/book.xml:17923 ../source/book.xml:18176 ../source/book.xml:18288 ../source/book.xml:18341 ../source/book.xml:18445 ../source/book.xml:18646 ../source/book.xml:18764 ../source/book.xml:18858 ../source/book.xml:19082 ../source/book.xml:19204 ../source/book.xml:19289 ../source/book.xml:19396 ../source/book.xml:19475 ../source/book.xml:19554 ../source/book.xml:19635 ../source/book.xml:19723 ../source/book.xml:19848 ../source/book.xml:19937 ../source/book.xml:20043 ../source/book.xml:20388 ../source/book.xml:20550 ../source/book.xml:20637
883 #: ../source/book.xml:984
884 msgid "The command-line client program."
887 #.(term), (command), (primary), (refname)
888 #: ../source/book.xml:988 ../source/book.xml:23115 ../source/book.xml:23120 ../source/book.xml:23123
893 #: ../source/book.xml:990
894 msgid "A program for reporting the state (in terms of revisions of the items present) of a working copy."
897 #.(term), (title), (command), (primary)
898 #: ../source/book.xml:995 ../source/book.xml:9943 ../source/book.xml:21711 ../source/book.xml:21809 ../source/book.xml:21853 ../source/book.xml:21908 ../source/book.xml:21998 ../source/book.xml:22042 ../source/book.xml:22111 ../source/book.xml:22156 ../source/book.xml:22188 ../source/book.xml:22251 ../source/book.xml:22299 ../source/book.xml:22348 ../source/book.xml:22392 ../source/book.xml:22445 ../source/book.xml:22507 ../source/book.xml:22560 ../source/book.xml:22598
903 #: ../source/book.xml:997
904 msgid "A tool for directly inspecting a Subversion repository."
907 #.(term), (title), (command), (primary)
908 #: ../source/book.xml:1001 ../source/book.xml:9913 ../source/book.xml:20781 ../source/book.xml:20931 ../source/book.xml:20990 ../source/book.xml:21029 ../source/book.xml:21132 ../source/book.xml:21165 ../source/book.xml:21211 ../source/book.xml:21243 ../source/book.xml:21289 ../source/book.xml:21352 ../source/book.xml:21398 ../source/book.xml:21436 ../source/book.xml:21513 ../source/book.xml:21557 ../source/book.xml:21605 ../source/book.xml:21662
913 #: ../source/book.xml:1003
914 msgid "A tool for creating, tweaking or repairing a Subversion repository."
918 #: ../source/book.xml:1008 ../source/book.xml:10055
919 msgid "svndumpfilter"
923 #: ../source/book.xml:1010
924 msgid "A program for filtering Subversion repository dump streams."
927 #.(term), (command), (literal)
928 #: ../source/book.xml:1015 ../source/book.xml:15382 ../source/book.xml:23252 ../source/book.xml:23257
933 #: ../source/book.xml:1017
934 msgid "A plug-in module for the Apache HTTP Server, used to make your repository available to others over a network."
937 #.(term), (literal), (entry), (command)
938 #: ../source/book.xml:1023 ../source/book.xml:1598 ../source/book.xml:11721 ../source/book.xml:22953
943 #: ../source/book.xml:1025
944 msgid "A custom standalone server program, runnable as a daemon process or invokable by SSH; another way to make your repository available to others over a network."
947 #.(term), (title), (command), (primary)
948 #: ../source/book.xml:1031 ../source/book.xml:10105 ../source/book.xml:22638 ../source/book.xml:22737 ../source/book.xml:22803 ../source/book.xml:22874
953 #: ../source/book.xml:1033
954 msgid "A program for incrementally mirroring one repository to another over a network."
958 #: ../source/book.xml:1038
959 msgid "Assuming you have Subversion installed correctly, you should be ready to start. The next two chapters will walk you through the use of <command>svn</command>, Subversion's command-line client program."
963 #: ../source/book.xml:1052
964 msgid "Fundamental Concepts"
968 #: ../source/book.xml:1054
969 msgid "This chapter is a short, casual introduction to Subversion. If you're new to version control, this chapter is definitely for you. We begin with a discussion of general version control concepts, work our way into the specific ideas behind Subversion, and show some simple examples of Subversion in use."
973 #: ../source/book.xml:1060
974 msgid "Even though the examples in this chapter show people sharing collections of program source code, keep in mind that Subversion can manage any sort of file collection—it's not limited to helping computer programmers."
978 #: ../source/book.xml:1069
979 msgid "The Repository"
983 #: ../source/book.xml:1071
984 msgid "Subversion is a centralized system for sharing information. At its core is a repository, which is a central store of data. The repository stores information in the form of a <firstterm>filesystem tree</firstterm>—a typical hierarchy of files and directories. Any number of <firstterm>clients</firstterm> connect to the repository, and then read or write to these files. By writing data, a client makes the information available to others; by reading data, the client receives information from others. <xref linkend=\"svn.basic.repository.dia-1\"/> illustrates this."
988 #: ../source/book.xml:1082
989 msgid "A typical client/server system"
993 #: ../source/book.xml:1090
994 msgid "So why is this interesting? So far, this sounds like the definition of a typical file server. And indeed, the repository <emphasis>is</emphasis> a kind of file server, but it's not your usual breed. What makes the Subversion repository special is that <emphasis>it remembers every change</emphasis> ever written to it: every change to every file, and even changes to the directory tree itself, such as the addition, deletion, and rearrangement of files and directories."
998 #: ../source/book.xml:1098
999 msgid "When a client reads data from the repository, it normally sees only the latest version of the filesystem tree. But the client also has the ability to view <emphasis>previous</emphasis> states of the filesystem. For example, a client can ask historical questions like, <quote>What did this directory contain last Wednesday?</quote> or <quote>Who was the last person to change this file, and what changes did he make?</quote> These are the sorts of questions that are at the heart of any <firstterm>version control system</firstterm>: systems that are designed to track changes to data over time."
1003 #: ../source/book.xml:1115
1004 msgid "Versioning Models"
1008 #: ../source/book.xml:1117
1009 msgid "The core mission of a version control system is to enable collaborative editing and sharing of data. But different systems use different strategies to achieve this. It's important to understand these different strategies for a couple of reasons. First, it will help you compare and contrast existing version control systems, in case you encounter other systems similar to Subversion. Beyond that, it will also help you make more effective use of Subversion, since Subversion itself supports a couple of different ways of working."
1013 #: ../source/book.xml:1129
1014 msgid "The Problem of File-Sharing"
1018 #: ../source/book.xml:1131
1019 msgid "All version control systems have to solve the same fundamental problem: how will the system allow users to share information, but prevent them from accidentally stepping on each other's feet? It's all too easy for users to accidentally overwrite each other's changes in the repository."
1023 #: ../source/book.xml:1137
1024 msgid "Consider the scenario shown in <xref linkend=\"svn.basic.vsn-models.problem-sharing.dia-1\"/>. Suppose we have two co-workers, Harry and Sally. They each decide to edit the same repository file at the same time. If Harry saves his changes to the repository first, then it's possible that (a few moments later) Sally could accidentally overwrite them with her own new version of the file. While Harry's version of the file won't be lost forever (because the system remembers every change), any changes Harry made <emphasis>won't</emphasis> be present in Sally's newer version of the file, because she never saw Harry's changes to begin with. Harry's work is still effectively lost—or at least missing from the latest version of the file—and probably by accident. This is definitely a situation we want to avoid!"
1028 #: ../source/book.xml:1153
1029 msgid "The problem to avoid"
1033 #: ../source/book.xml:1165
1034 msgid "The Lock-Modify-Unlock Solution"
1038 #: ../source/book.xml:1167
1039 msgid "Many version control systems use a <firstterm>lock-modify-unlock</firstterm> model to address the problem of many authors clobbering each other's work. In this model, the repository allows only one person to change a file at a time. This exclusivity policy is managed using locks. Harry must <quote>lock</quote> a file before he can begin making changes to it. If Harry has locked a file, then Sally cannot also lock it, and therefore cannot make any changes to that file. All she can do is read the file, and wait for Harry to finish his changes and release his lock. After Harry unlocks the file, Sally can take her turn by locking and editing the file. <xref linkend=\"svn.basic.vsn-models.lock-unlock.dia-1\"/> demonstrates this simple solution."
1043 #: ../source/book.xml:1182
1044 msgid "The lock-modify-unlock solution"
1048 #: ../source/book.xml:1190
1049 msgid "The problem with the lock-modify-unlock model is that it's a bit restrictive, and often becomes a roadblock for users:"
1053 #: ../source/book.xml:1195
1054 msgid "<emphasis>Locking may cause administrative problems.</emphasis> Sometimes Harry will lock a file and then forget about it. Meanwhile, because Sally is still waiting to edit the file, her hands are tied. And then Harry goes on vacation. Now Sally has to get an administrator to release Harry's lock. The situation ends up causing a lot of unnecessary delay and wasted time."
1058 #: ../source/book.xml:1206
1059 msgid "<emphasis>Locking may cause unnecessary serialization.</emphasis> What if Harry is editing the beginning of a text file, and Sally simply wants to edit the end of the same file? These changes don't overlap at all. They could easily edit the file simultaneously, and no great harm would come, assuming the changes were properly merged together. There's no need for them to take turns in this situation."
1063 #: ../source/book.xml:1218
1064 msgid "<emphasis>Locking may create a false sense of security.</emphasis> Suppose Harry locks and edits file A, while Sally simultaneously locks and edits file B. But what if A and B depend on one another, and the changes made to each are semantically incompatible? Suddenly A and B don't work together anymore. The locking system was powerless to prevent the problem—yet it somehow provided a false sense of security. It's easy for Harry and Sally to imagine that by locking files, each is beginning a safe, insulated task, and thus not bother discussing their incompatible changes early on. Locking often becomes a substitute for real communication."
1068 #: ../source/book.xml:1238
1069 msgid "The Copy-Modify-Merge Solution"
1073 #: ../source/book.xml:1240
1074 msgid "Subversion, CVS, and many other version control systems use a <firstterm>copy-modify-merge</firstterm> model as an alternative to locking. In this model, each user's client contacts the project repository and creates a personal <firstterm>working copy</firstterm>—a local reflection of the repository's files and directories. Users then work simultaneously and independently, modifying their private copies. Finally, the private copies are merged together into a new, final version. The version control system often assists with the merging, but ultimately a human being is responsible for making it happen correctly."
1078 #: ../source/book.xml:1251
1079 msgid "Here's an example. Say that Harry and Sally each create working copies of the same project, copied from the repository. They work concurrently, and make changes to the same file A within their copies. Sally saves her changes to the repository first. When Harry attempts to save his changes later, the repository informs him that his file A is <firstterm>out-of-date</firstterm>. In other words, that file A in the repository has somehow changed since he last copied it. So Harry asks his client to <firstterm>merge</firstterm> any new changes from the repository into his working copy of file A. Chances are that Sally's changes don't overlap with his own; so once he has both sets of changes integrated, he saves his working copy back to the repository. <xref linkend=\"svn.basic.vsn-models.copy-merge.dia-1\"/> and <xref linkend=\"svn.basic.vsn-models.copy-merge.dia-2\"/> show this process."
1083 #: ../source/book.xml:1267
1084 msgid "The copy-modify-merge solution"
1088 #: ../source/book.xml:1277
1089 msgid "The copy-modify-merge solution (continued)"
1093 #: ../source/book.xml:1285
1094 msgid "But what if Sally's changes <emphasis>do</emphasis> overlap with Harry's changes? What then? This situation is called a <firstterm>conflict</firstterm>, and it's usually not much of a problem. When Harry asks his client to merge the latest repository changes into his working copy, his copy of file A is somehow flagged as being in a state of conflict: he'll be able to see both sets of conflicting changes, and manually choose between them. Note that software can't automatically resolve conflicts; only humans are capable of understanding and making the necessary intelligent choices. Once Harry has manually resolved the overlapping changes—perhaps after a discussion with Sally—he can safely save the merged file back to the repository."
1098 #: ../source/book.xml:1298
1099 msgid "The copy-modify-merge model may sound a bit chaotic, but in practice, it runs extremely smoothly. Users can work in parallel, never waiting for one another. When they work on the same files, it turns out that most of their concurrent changes don't overlap at all; conflicts are infrequent. And the amount of time it takes to resolve conflicts is usually far less than the time lost by a locking system."
1103 #: ../source/book.xml:1305
1104 msgid "In the end, it all comes down to one critical factor: user communication. When users communicate poorly, both syntactic and semantic conflicts increase. No system can force users to communicate perfectly, and no system can detect semantic conflicts. So there's no point in being lulled into a false sense of security that a locking system will somehow prevent conflicts; in practice, locking seems to inhibit productivity more than anything else."
1108 #: ../source/book.xml:1315
1109 msgid "When Locking is Necessary"
1113 #: ../source/book.xml:1317
1114 msgid "While the lock-modify-unlock model is considered generally harmful to collaboration, there are still times when locking is appropriate."
1118 #: ../source/book.xml:1320
1119 msgid "The copy-modify-merge model is based on the assumption that files are contextually mergeable: that is, that the majority of the files in the repository are line-based text files (such as program source code). But for files with binary formats, such as artwork or sound, it's often impossible to merge conflicting changes. In these situations, it really is necessary to users to take strict turns when changing the file. Without serialized access, somebody ends up wasting time on changes that are ultimately discarded."
1123 #: ../source/book.xml:1330
1124 msgid "While Subversion is still primarily a copy-modify-merge system, it still recognizes the need to lock an occasional file and thus provide mechanisms for this. This feature is discussed later in this book, in <xref linkend=\"svn.advanced.locking\"/>."
1128 #: ../source/book.xml:1344
1129 msgid "Subversion in Action"
1133 #: ../source/book.xml:1346
1134 msgid "It's time to move from the abstract to the concrete. In this section, we'll show real examples of Subversion being used."
1138 #: ../source/book.xml:1352
1139 msgid "Subversion Repository URLs"
1143 #: ../source/book.xml:1354
1144 msgid "Throughout this book, Subversion uses URLs to identify versioned files and directories in Subversion repositories. For the most part, these URLs use the standard syntax, allowing for server names and port numbers to be specified as part of the URL:"
1148 #: ../source/book.xml:1359
1150 msgid "\n$ svn checkout http://svn.example.com:9834/repos\n…\n"
1154 #: ../source/book.xml:1363
1155 msgid "But there are some nuances in Subversion's handling of URLs that are notable. For example, URLs containing the <literal>file://</literal> access method (used for local repositories) must, in accordance with convention, have either a server name of <literal>localhost</literal> or no server name at all:"
1159 #: ../source/book.xml:1369
1161 msgid "\n$ svn checkout file:///path/to/repos\n…\n$ svn checkout file://localhost/path/to/repos\n…\n"
1165 #: ../source/book.xml:1375
1166 msgid "Also, users of the <literal>file://</literal> scheme on Windows platforms will need to use an unofficially <quote>standard</quote> syntax for accessing repositories that are on the same machine, but on a different drive than the client's current working drive. Either of the two following URL path syntaxes will work where <literal>X</literal> is the drive on which the repository resides:"
1170 #: ../source/book.xml:1383
1172 msgid "\nC:\\> svn checkout file:///X:/path/to/repos\n…\nC:\\> svn checkout \"file:///X|/path/to/repos\"\n…\n"
1176 #: ../source/book.xml:1389
1177 msgid "In the second syntax, you need to quote the URL so that the vertical bar character is not interpreted as a pipe. Also, note that a URL uses forward slashes even though the native (non-URL) form of a path on Windows uses backslashes."
1181 #: ../source/book.xml:1394
1182 msgid "Subversion's <literal>file://</literal> URLs cannot be used in a regular web browser the way typical <literal>file://</literal> URLs can. When you attempt to view a <literal>file://</literal> URL in a regular web browser, it reads and displays the contents of the file at that location by examining the filesystem directly. However, Subversion's resources exist in a virtual filesystem (see <xref linkend=\"svn.developer.layerlib.repos\"/>), and your browser will not understand how to interact with that filesystem."
1186 #: ../source/book.xml:1404
1187 msgid "Finally, it should be noted that the Subversion client will automatically encode URLs as necessary, just like a web browser does. For example, if a URL contains a space or upper-ASCII character:"
1191 #: ../source/book.xml:1408
1193 msgid "\n$ svn checkout \"http://host/path with space/project/españa\"\n"
1197 #: ../source/book.xml:1411
1198 msgid "…then Subversion will escape the unsafe characters and behave as if you had typed:"
1202 #: ../source/book.xml:1413
1204 msgid "\n$ svn checkout http://host/path%20with%20space/project/espa%C3%B1a\n"
1208 #: ../source/book.xml:1416
1209 msgid "If the URL contains spaces, be sure to place it within quote marks, so that your shell treats the whole thing as a single argument to the <command>svn</command> program."
1213 #: ../source/book.xml:1423
1214 msgid "Working Copies"
1218 #: ../source/book.xml:1425
1219 msgid "You've already read about working copies; now we'll demonstrate how the Subversion client creates and uses them."
1223 #: ../source/book.xml:1428
1224 msgid "A Subversion working copy is an ordinary directory tree on your local system, containing a collection of files. You can edit these files however you wish, and if they're source code files, you can compile your program from them in the usual way. Your working copy is your own private work area: Subversion will never incorporate other people's changes, nor make your own changes available to others, until you explicitly tell it to do so. You can even have multiple working copies of the same project."
1228 #: ../source/book.xml:1437
1229 msgid "After you've made some changes to the files in your working copy and verified that they work properly, Subversion provides you with commands to <quote>publish</quote> your changes to the other people working with you on your project (by writing to the repository). If other people publish their own changes, Subversion provides you with commands to merge those changes into your working directory (by reading from the repository)."
1233 #: ../source/book.xml:1445
1234 msgid "A working copy also contains some extra files, created and maintained by Subversion, to help it carry out these commands. In particular, each directory in your working copy contains a subdirectory named <filename>.svn</filename>, also known as the working copy <firstterm>administrative directory</firstterm>. The files in each administrative directory help Subversion recognize which files contain unpublished changes, and which files are out-of-date with respect to others' work."
1238 #: ../source/book.xml:1454
1239 msgid "A typical Subversion repository often holds the files (or source code) for several projects; usually, each project is a subdirectory in the repository's filesystem tree. In this arrangement, a user's working copy will usually correspond to a particular subtree of the repository."
1243 #: ../source/book.xml:1459
1244 msgid "For example, suppose you have a repository that contains two software projects, <literal>paint</literal> and <literal>calc</literal>. Each project lives in its own top-level subdirectory, as shown in <xref linkend=\"svn.basic.in-action.wc.dia-1\"/>."
1248 #: ../source/book.xml:1465
1249 msgid "The repository's filesystem"
1253 #: ../source/book.xml:1473
1254 msgid "To get a working copy, you must <firstterm>check out</firstterm> some subtree of the repository. (The term <quote>check out</quote> may sound like it has something to do with locking or reserving resources, but it doesn't; it simply creates a private copy of the project for you.) For example, if you check out <filename>/calc</filename>, you will get a working copy like this:"
1258 #: ../source/book.xml:1480
1260 msgid "\n$ svn checkout http://svn.example.com/repos/calc\nA calc/Makefile\nA calc/integer.c\nA calc/button.c\nChecked out revision 56.\n\n$ ls -A calc\nMakefile integer.c button.c .svn/\n"
1264 #: ../source/book.xml:1490
1265 msgid "The list of letter A's in the left margin indicates that Subversion is adding a number of items to your working copy. You now have a personal copy of the repository's <filename>/calc</filename> directory, with one additional entry—<filename>.svn</filename>—which holds the extra information needed by Subversion, as mentioned earlier."
1269 #: ../source/book.xml:1497
1270 msgid "Suppose you make changes to <filename>button.c</filename>. Since the <filename>.svn</filename> directory remembers the file's original modification date and contents, Subversion can tell that you've changed the file. However, Subversion does not make your changes public until you explicitly tell it to. The act of publishing your changes is more commonly known as <firstterm>committing</firstterm> (or <firstterm>checking in</firstterm>) changes to the repository."
1274 #: ../source/book.xml:1505
1275 msgid "To publish your changes to others, you can use Subversion's <command>commit</command> command."
1279 #: ../source/book.xml:1507
1281 msgid "\n$ svn commit button.c -m \"Fixed a typo in button.c.\"\nSending button.c\nTransmitting file data .\nCommitted revision 57.\n"
1285 #: ../source/book.xml:1513
1286 msgid "Now your changes to <filename>button.c</filename> have been committed to the repository, with a note describing your change (namely, that you fixed a typo). If another user checks out a working copy of <filename>/calc</filename>, they will see your changes in the latest version of the file."
1290 #: ../source/book.xml:1519
1291 msgid "Suppose you have a collaborator, Sally, who checked out a working copy of <filename>/calc</filename> at the same time you did. When you commit your change to <filename>button.c</filename>, Sally's working copy is left unchanged; Subversion only modifies working copies at the user's request."
1295 #: ../source/book.xml:1525
1296 msgid "To bring her project up to date, Sally can ask Subversion to <firstterm>update</firstterm> her working copy, by using the Subversion <command>update</command> command. This will incorporate your changes into her working copy, as well as any others that have been committed since she checked it out."
1300 #: ../source/book.xml:1531
1302 msgid "\n$ pwd\n/home/sally/calc\n\n$ ls -A \n.svn/ Makefile integer.c button.c\n\n$ svn update\nU button.c\nUpdated to revision 57.\n"
1306 #: ../source/book.xml:1542
1307 msgid "The output from the <command>svn update</command> command indicates that Subversion updated the contents of <filename>button.c</filename>. Note that Sally didn't need to specify which files to update; Subversion uses the information in the <filename>.svn</filename> directory, and further information in the repository, to decide which files need to be brought up to date."
1311 #: ../source/book.xml:1551
1312 msgid "Repository URLs"
1316 #: ../source/book.xml:1553
1317 msgid "Subversion repositories can be accessed through many different methods—on local disk, or through various network protocols, depending on how your administrator has set things up for you. A repository location, however, is always a URL. <xref linkend=\"svn.basic.in-action.wc.tbl-1\"/> describes how different URL schemes map to the available access methods."
1321 #: ../source/book.xml:1563
1322 msgid "Repository Access URLs"
1326 #: ../source/book.xml:1568
1331 #: ../source/book.xml:1569
1332 msgid "Access Method"
1336 #: ../source/book.xml:1575
1341 #: ../source/book.xml:1577
1342 msgid "direct repository access (on local disk)"
1346 #: ../source/book.xml:1581 ../source/book.xml:1590
1351 #: ../source/book.xml:1583
1352 msgid "access via WebDAV protocol to Subversion-aware Apache server"
1356 #: ../source/book.xml:1588
1361 #: ../source/book.xml:1590
1362 msgid "same as <placeholder-1/>, but with SSL encryption."
1366 #: ../source/book.xml:1595 ../source/book.xml:1604
1371 #: ../source/book.xml:1597
1372 msgid "access via custom protocol to an <placeholder-1/> server"
1376 #: ../source/book.xml:1602
1381 #: ../source/book.xml:1604
1382 msgid "same as <placeholder-1/>, but through an SSH tunnel."
1386 #: ../source/book.xml:1610
1387 msgid "For more information on how Subversion parses URLs, see <xref linkend=\"svn.advanced.reposurls\"/>. For more information on the different types of network servers available for Subversion, see <xref linkend=\"svn.serverconfig\"/>."
1391 #: ../source/book.xml:1620
1396 #: ../source/book.xml:1622
1397 msgid "An <command>svn commit</command> operation publishes changes to any number of files and directories as a single atomic transaction. In your working copy, you can change files' contents; create, delete, rename and copy files and directories; then commit a complete set of changes as an atomic transaction."
1401 #: ../source/book.xml:1628
1402 msgid "By <quote>atomic transaction</quote>, we mean simply this: either all of the changes happen in the repository, or none of them happen. Subversion tries to retain this atomicity in the face of program crashes, system crashes, network problems, and other users' actions."
1406 #: ../source/book.xml:1633
1407 msgid "Each time the repository accepts a commit, this creates a new state of the filesystem tree, called a <firstterm>revision</firstterm>. Each revision is assigned a unique natural number, one greater than the number of the previous revision. The initial revision of a freshly created repository is numbered zero, and consists of nothing but an empty root directory."
1411 #: ../source/book.xml:1640
1412 msgid "<xref linkend=\"svn.basic.in-action.revs.dia-1\"/> illustrates a nice way to visualize the repository. Imagine an array of revision numbers, starting at 0, stretching from left to right. Each revision number has a filesystem tree hanging below it, and each tree is a <quote>snapshot</quote> of the way the repository looked after a commit."
1416 #: ../source/book.xml:1648
1417 msgid "The repository"
1421 #: ../source/book.xml:1658
1422 msgid "Global Revision Numbers"
1426 #: ../source/book.xml:1660
1427 msgid "Unlike most version control systems, Subversion's revision numbers apply to <emphasis>entire trees</emphasis>, not individual files. Each revision number selects an entire tree, a particular state of the repository after some committed change. Another way to think about it is that revision N represents the state of the repository filesystem after the Nth commit. When Subversion users talk about <quote>revision 5 of <filename>foo.c</filename></quote>, they really mean <quote><filename>foo.c</filename> as it appears in revision 5.</quote> Notice that in general, revisions N and M of a file do <emphasis>not</emphasis> necessarily differ! Many other version control systems use per-file revision numbers, so this concept may seem unusual at first. (Former CVS users might want to see <xref linkend=\"svn.forcvs\"/> for more details.)"
1431 #: ../source/book.xml:1677
1432 msgid "It's important to note that working copies do not always correspond to any single revision in the repository; they may contain files from several different revisions. For example, suppose you check out a working copy from a repository whose most recent revision is 4:"
1436 #: ../source/book.xml:1682
1438 msgid "\ncalc/Makefile:4\n integer.c:4\n button.c:4\n"
1442 #: ../source/book.xml:1687
1443 msgid "At the moment, this working directory corresponds exactly to revision 4 in the repository. However, suppose you make a change to <filename>button.c</filename>, and commit that change. Assuming no other commits have taken place, your commit will create revision 5 of the repository, and your working copy will now look like this:"
1447 #: ../source/book.xml:1693
1449 msgid "\ncalc/Makefile:4\n integer.c:4\n button.c:5\n"
1453 #: ../source/book.xml:1698
1454 msgid "Suppose that, at this point, Sally commits a change to <filename>integer.c</filename>, creating revision 6. If you use <command>svn update</command> to bring your working copy up to date, then it will look like this:"
1458 #: ../source/book.xml:1702
1460 msgid "\ncalc/Makefile:6\n integer.c:6\n button.c:6\n"
1464 #: ../source/book.xml:1707
1465 msgid "Sally's change to <filename>integer.c</filename> will appear in your working copy, and your change will still be present in <filename>button.c</filename>. In this example, the text of <filename>Makefile</filename> is identical in revisions 4, 5, and 6, but Subversion will mark your working copy of <filename>Makefile</filename> with revision 6 to indicate that it is still current. So, after you do a clean update at the top of your working copy, it will generally correspond to exactly one revision in the repository."
1469 #: ../source/book.xml:1720
1470 msgid "How Working Copies Track the Repository"
1474 #: ../source/book.xml:1722
1475 msgid "For each file in a working directory, Subversion records two essential pieces of information in the <filename>.svn/</filename> administrative area:"
1479 #: ../source/book.xml:1727
1480 msgid "what revision your working file is based on (this is called the file's <firstterm>working revision</firstterm>), and"
1484 #: ../source/book.xml:1732
1485 msgid "a timestamp recording when the local copy was last updated by the repository."
1489 #: ../source/book.xml:1736
1490 msgid "Given this information, by talking to the repository, Subversion can tell which of the following four states a working file is in:"
1494 #: ../source/book.xml:1741
1495 msgid "Unchanged, and current"
1499 #: ../source/book.xml:1743
1500 msgid "The file is unchanged in the working directory, and no changes to that file have been committed to the repository since its working revision. An <command>svn commit</command> of the file will do nothing, and an <command>svn update</command> of the file will do nothing."
1504 #: ../source/book.xml:1752
1505 msgid "Locally changed, and current"
1509 #: ../source/book.xml:1754
1510 msgid "The file has been changed in the working directory, and no changes to that file have been committed to the repository since you last updated. There are local changes that have not been committed to the repository, thus an <command>svn commit</command> of the file will succeed in publishing your changes, and an <command>svn update</command> of the file will do nothing."
1514 #: ../source/book.xml:1764
1515 msgid "Unchanged, and out-of-date"
1519 #: ../source/book.xml:1766
1520 msgid "The file has not been changed in the working directory, but it has been changed in the repository. The file should eventually be updated, to make it current with the latest public revision. An <command>svn commit</command> of the file will do nothing, and an <command>svn update</command> of the file will fold the latest changes into your working copy."
1524 #: ../source/book.xml:1776
1525 msgid "Locally changed, and out-of-date"
1529 #: ../source/book.xml:1778
1530 msgid "The file has been changed both in the working directory, and in the repository. An <command>svn commit</command> of the file will fail with an <quote>out-of-date</quote> error. The file should be updated first; an <command>svn update</command> command will attempt to merge the public changes with the local changes. If Subversion can't complete the merge in a plausible way automatically, it leaves it to the user to resolve the conflict."
1534 #: ../source/book.xml:1790
1535 msgid "This may sound like a lot to keep track of, but the <command>svn status</command> command will show you the state of any item in your working copy. For more information on that command, see <xref linkend=\"svn.tour.cycle.examine.status\"/>."
1539 #: ../source/book.xml:1799
1540 msgid "Mixed Revision Working Copies"
1544 #: ../source/book.xml:1801
1545 msgid "As a general principle, Subversion tries to be as flexible as possible. One special kind of flexibility is the ability to have a working copy containing files and directories with a mix of different working revision numbers. Unfortunately, this flexibility tends to confuse a number of new users. If the earlier example showing mixed revisions perplexed you, here's a primer on both why the feature exists and how to make use of it."
1549 #: ../source/book.xml:1812
1550 msgid "Updates and Commits are Separate"
1554 #: ../source/book.xml:1814
1555 msgid "One of the fundamental rules of Subversion is that a <quote>push</quote> action does not cause a <quote>pull</quote>, nor the other way around. Just because you're ready to submit new changes to the repository doesn't mean you're ready to receive changes from other people. And if you have new changes still in progress, then <command>svn update</command> should gracefully merge repository changes into your own, rather than forcing you to publish them."
1559 #: ../source/book.xml:1823
1560 msgid "The main side-effect of this rule is that it means a working copy has to do extra bookkeeping to track mixed revisions, and be tolerant of the mixture as well. It's made more complicated by the fact that directories themselves are versioned."
1564 #: ../source/book.xml:1828
1565 msgid "For example, suppose you have a working copy entirely at revision 10. You edit the file <filename>foo.html</filename> and then perform an <command>svn commit</command>, which creates revision 15 in the repository. After the commit succeeds, many new users would expect the working copy to be entirely at revision 15, but that's not the case! Any number of changes might have happened in the repository between revisions 10 and 15. The client knows nothing of those changes in the repository, since you haven't yet run <command>svn update</command>, and <command>svn commit</command> doesn't pull down new changes. If, on the other hand, <command>svn commit</command><emphasis>were</emphasis> to automatically download the newest changes, then it would be possible to set the entire working copy to revision 15—but then we'd be breaking the fundamental rule of <quote>push</quote> and <quote>pull</quote> remaining separate actions. Therefore the only safe thing the Subversion client can do is mark the one file—<filename>foo.html</filename>—as being at revision 15. The rest of the working copy remains at revision 10. Only by running <command>svn update</command> can the latest changes be downloaded, and the whole working copy be marked as revision 15."
1569 #: ../source/book.xml:1856
1570 msgid "Mixed revisions are normal"
1574 #: ../source/book.xml:1858
1575 msgid "The fact is, <emphasis>every time</emphasis> you run <command>svn commit</command>, your working copy ends up with some mixture of revisions. The things you just committed are marked as having larger working revisions than everything else. After several commits (with no updates in-between) your working copy will contain a whole mixture of revisions. Even if you're the only person using the repository, you will still see this phenomenon. To examine your mixture of working revisions, use the <command>svn status --verbose</command> command (see <xref linkend=\"svn.tour.cycle.examine.status\"/> for more information.)"
1579 #: ../source/book.xml:1869
1580 msgid "Often, new users are completely unaware that their working copy contains mixed revisions. This can be confusing, because many client commands are sensitive to the working revision of the item they're examining. For example, the <command>svn log</command> command is used to display the history of changes to a file or directory (see <xref linkend=\"svn.tour.history.log\"/>). When the user invokes this command on a working copy object, they expect to see the entire history of the object. But if the object's working revision is quite old (often because <command>svn update</command> hasn't been run in a long time), then the history of the <emphasis>older</emphasis> version of the object is shown."
1584 #: ../source/book.xml:1886
1585 msgid "Mixed revisions are useful"
1589 #: ../source/book.xml:1888
1590 msgid "If your project is sufficiently complex, you'll discover that it's sometimes nice to forcibly <firstterm>backdate</firstterm> (or, update to a revision older than the one you already have) portions of your working copy to an earlier revision; you'll learn how to do that in <xref linkend=\"svn.tour\"/>. Perhaps you'd like to test an earlier version of a sub-module contained in a subdirectory, or perhaps you'd like to figure out when a bug first came into existence in a specific file. This is the <quote>time machine</quote> aspect of a version control system—the feature which allows you to move any portion of your working copy forward and backward in history."
1594 #: ../source/book.xml:1904
1595 msgid "Mixed revisions have limitations"
1599 #: ../source/book.xml:1906
1600 msgid "However you make use of mixed revisions in your working copy, there are limitations to this flexibility."
1604 #: ../source/book.xml:1908
1605 msgid "First, you cannot commit the deletion of a file or directory which isn't fully up-to-date. If a newer version of the item exists in the repository, your attempt to delete will be rejected, to prevent you from accidentally destroying changes you've not yet seen."
1609 #: ../source/book.xml:1913
1610 msgid "Second, you cannot commit a metadata change to a directory unless it's fully up-to-date. You'll learn about attaching <quote>properties</quote> to items in <xref linkend=\"svn.advanced\"/>. A directory's working revision defines a specific set of entries and properties, and thus committing a property change to an out-of-date directory may destroy properties you've not yet seen."
1614 #: ../source/book.xml:1927 ../source/book.xml:3706 ../source/book.xml:8944 ../source/book.xml:11627
1619 #: ../source/book.xml:1929
1620 msgid "We've covered a number of fundamental Subversion concepts in this chapter:"
1624 #: ../source/book.xml:1933
1625 msgid "We've introduced the notions of the central repository, the client working copy, and the array of repository revision trees."
1629 #: ../source/book.xml:1938
1630 msgid "We've seen some simple examples of how two collaborators can use Subversion to publish and receive changes from one another, using the <quote>copy-modify-merge</quote> model."
1634 #: ../source/book.xml:1944
1635 msgid "We've talked a bit about the way Subversion tracks and manages information in a working copy."
1639 #: ../source/book.xml:1948
1640 msgid "At this point, you should have a good idea of how Subversion works in the most general sense. Armed with this knowledge, you should now be ready to move into the next chapter, which is a detailed tour of Subversion's commands and features."
1644 #: ../source/book.xml:1961
1649 #: ../source/book.xml:1963
1650 msgid "Now we will go into the details of using Subversion. By the time you reach the end of this chapter, you will be able to perform all the tasks you need to use Subversion in a normal day's work. You'll start with getting your files into Subversion, followed by an initial checkout of your code. We'll then walk you through making changes and examining those changes. You'll also see how to bring changes made by others into your working copy, examine them, and work through any conflicts that might arise."
1654 #: ../source/book.xml:1972
1655 msgid "Note that this chapter is not meant to be an exhaustive list of all Subversion's commands—rather, it's a conversational introduction to the most common Subversion tasks you'll encounter. This chapter assumes that you've read and understood <xref linkend=\"svn.basic\"/> and are familiar with the general model of Subversion. For a complete reference of all commands, see <xref linkend=\"svn.ref\"/>."
1658 #.(title), (refpurpose)
1659 #: ../source/book.xml:1984 ../source/book.xml:18294 ../source/book.xml:21138 ../source/book.xml:22162
1664 #: ../source/book.xml:1986
1665 msgid "Before reading on, here is the most important command you'll ever need when using Subversion: <command>svn help</command>. The Subversion command-line client is self-documenting—at any time, a quick <command>svn help <replaceable>SUBCOMMAND</replaceable></command> will describe the syntax, options, and behavior of the subcommand."
1669 #: ../source/book.xml:1992
1671 msgid "\n$ svn help import\nimport: Commit an unversioned file or tree into the repository.\nusage: import [PATH] URL\n\n Recursively commit a copy of PATH to URL.\n If PATH is omitted '.' is assumed.\n Parent directories are created as necessary in the repository.\n If PATH is a directory, the contents of the directory are added\n directly under URL.\n\nValid options:\n -q [--quiet] : print as little as possible\n -N [--non-recursive] : operate on single directory only\n…\n"
1675 #: ../source/book.xml:2014
1676 msgid "Getting Data into your Repository"
1680 #: ../source/book.xml:2016
1681 msgid "There are two ways to get new files into your Subversion repository: <command>svn import</command> and <command>svn add</command>. We'll discuss <command>svn import</command> here and <command>svn add</command> later in this chapter when we review a typical day with Subversion."
1684 #.(title), (refname)
1685 #: ../source/book.xml:2024 ../source/book.xml:18346
1690 #: ../source/book.xml:2026
1691 msgid "The <command>svn import</command> command is a quick way to copy an unversioned tree of files into a repository, creating intermediate directories as necessary. <command>svn import</command> doesn't require a working copy, and your files are immediately committed to the repository. This is typically used when you have an existing tree of files that you want to begin tracking in your Subversion repository. For example:"
1695 #: ../source/book.xml:2033
1697 msgid "\n$ svnadmin create /usr/local/svn/newrepos\n$ svn import mytree file:///usr/local/svn/newrepos/some/project \\\n -m \"Initial import\"\nAdding mytree/foo.c\nAdding mytree/bar.c\nAdding mytree/subdir\nAdding mytree/subdir/quux.h\n\nCommitted revision 1.\n"
1701 #: ../source/book.xml:2044
1702 msgid "The previous example copied the contents of directory <filename>mytree</filename> under the directory <filename>some/project</filename> in the repository:"
1706 #: ../source/book.xml:2047
1708 msgid "\n$ svn list file:///usr/local/svn/newrepos/some/project\nbar.c\nfoo.c\nsubdir/\n"
1712 #: ../source/book.xml:2053
1713 msgid "Note that after the import is finished, the original tree is <emphasis>not</emphasis> converted into a working copy. To start working, you still need to <command>svn checkout</command> a fresh working copy of the tree."
1717 #: ../source/book.xml:2061
1718 msgid "Recommended repository layout"
1722 #: ../source/book.xml:2063
1723 msgid "While Subversion's flexibility allows you to layout your repository in any way that you choose, we recommend that you create a <filename>trunk</filename> directory to hold the <quote>main line</quote> of development, a <filename>branches</filename> directory to contain branch copies, and a <filename>tags</filename> directory to contain tag copies, for example:"
1727 #: ../source/book.xml:2070
1729 msgid "\n$ svn list file:///usr/local/svn/repos\n/trunk\n/branches\n/tags\n"
1733 #: ../source/book.xml:2076
1734 msgid "You'll learn more about tags and branches in <xref linkend=\"svn.branchmerge\"/>. For details and how to set up multiple projects, see <xref linkend=\"svn.branchmerge.maint.layout\"/> and <xref linkend=\"svn.reposadmin.projects.chooselayout\"/> to read more about <quote>project roots</quote>."
1738 #: ../source/book.xml:2086
1739 msgid "Initial Checkout"
1743 #: ../source/book.xml:2088
1744 msgid "Most of the time, you will start using a Subversion repository by doing a <firstterm>checkout</firstterm> of your project. Checking out a repository creates a <quote>working copy</quote> of it on your local machine. This copy contains the <literal>HEAD</literal> (latest revision) of the Subversion repository that you specify on the command line:"
1748 #: ../source/book.xml:2094
1750 msgid "\n$ svn checkout http://svn.collab.net/repos/svn/trunk\nA trunk/Makefile.in\nA trunk/ac-helpers\nA trunk/ac-helpers/install.sh\nA trunk/ac-helpers/install-sh\nA trunk/build.conf\n…\nChecked out revision 8810.\n"
1754 #: ../source/book.xml:2106
1755 msgid "What's in a Name?"
1759 #: ../source/book.xml:2108
1760 msgid "Subversion tries hard not to limit the type of data you can place under version control. The contents of files and property values are stored and transmitted as binary data, and <xref linkend=\"svn.advanced.props.special.mime-type\"/> tells you how to give Subversion a hint that <quote>textual</quote> operations don't make sense for a particular file. There are a few places, however, where Subversion places restrictions on information it stores."
1764 #: ../source/book.xml:2117
1765 msgid "Subversion internally handles certain bits of data—for example, property names, path names, and log messages—as UTF-8 encoded Unicode. This is not to say that all your interactions with Subversion must involve UTF-8, though. As a general rule, Subversion clients will gracefully and transparently handle conversions between UTF-8 and the encoding system in use on your computer, if such a conversion can meaningfully be done (which is the case for most common encodings in use today)."
1769 #: ../source/book.xml:2126
1770 msgid "In addition, path names are used as XML attribute values in WebDAV exchanges, as well in as some of Subversion's housekeeping files. This means that path names can only contain legal XML (1.0) characters. Subversion also prohibits TAB, CR, and LF characters in path names to prevent paths from being broken up in diffs, or in the output of commands like <xref linkend=\"svn.ref.svn.c.log\"/> or <xref linkend=\"svn.ref.svn.c.status\"/>."
1774 #: ../source/book.xml:2133
1775 msgid "While it may seem like a lot to remember, in practice these limitations are rarely a problem. As long as your locale settings are compatible with UTF-8, and you don't use control characters in path names, you should have no trouble communicating with Subversion. The command-line client adds an extra bit of help—it will automatically escape illegal path characters as needed in URLs you type to create <quote>legally correct</quote> versions for internal use."
1779 #: ../source/book.xml:2143
1780 msgid "Although the above example checks out the trunk directory, you can just as easily check out any deep subdirectory of a repository by specifying the subdirectory in the checkout URL:"
1784 #: ../source/book.xml:2147
1786 msgid "\n$ svn checkout \\\n http://svn.collab.net/repos/svn/trunk/subversion/tests/cmdline/\nA cmdline/revert_tests.py\nA cmdline/diff_tests.py\nA cmdline/autoprop_tests.py\nA cmdline/xmltests\nA cmdline/xmltests/svn-test.sh\n…\nChecked out revision 8810.\n"
1790 #: ../source/book.xml:2158
1791 msgid "Since Subversion uses a <quote>copy-modify-merge</quote> model instead of <quote>lock-modify-unlock</quote> (see <xref linkend=\"svn.basic.vsn-models\"/>), you can start right in making changes to the files and directories in your working copy. Your working copy is just like any other collection of files and directories on your system. You can edit and change them, move them around, you can even delete the entire working copy and forget about it."
1795 #: ../source/book.xml:2166
1796 msgid "While your working copy is <quote>just like any other collection of files and directories on your system</quote>, you can edit files at will, but you must tell Subversion about <emphasis>everything else</emphasis> that you do. For example, if you want to copy or move an item in a working copy, you should use <command>svn copy</command> or <command>svn move</command> instead of the copy and move commands provided by your operating system. We'll talk more about them later in this chapter."
1800 #: ../source/book.xml:2176
1801 msgid "Unless you're ready to commit the addition of a new file or directory, or changes to existing ones, there's no need to further notify the Subversion server that you've done anything."
1805 #: ../source/book.xml:2182
1806 msgid "What's with the <filename>.svn</filename> directory?"
1810 #: ../source/book.xml:2184
1811 msgid "Every directory in a working copy contains an administrative area, a subdirectory named <filename>.svn</filename>. Usually, directory listing commands won't show this subdirectory, but it is nevertheless an important directory. Whatever you do, don't delete or change anything in the administrative area! Subversion depends on it to manage your working copy."
1815 #: ../source/book.xml:2191
1816 msgid "If you accidentally remove the <filename>.svn</filename> subdirectory, the easiest way to fix the problem is to remove the entire containing directory (a normal system deletion, not <command>svn delete</command>), then run <command>svn update</command> from a parent directory. The Subversion client will re-download the directory you've deleted, with a new <filename>.svn</filename> area as well."
1820 #: ../source/book.xml:2199
1821 msgid "While you can certainly check out a working copy with the URL of the repository as the only argument, you can also specify a directory after your repository URL. This places your working copy in the new directory that you name. For example:"
1825 #: ../source/book.xml:2203
1827 msgid "\n$ svn checkout http://svn.collab.net/repos/svn/trunk subv\nA subv/Makefile.in\nA subv/ac-helpers\nA subv/ac-helpers/install.sh\nA subv/ac-helpers/install-sh\nA subv/build.conf\n…\nChecked out revision 8810.\n"
1831 #: ../source/book.xml:2213
1832 msgid "That will place your working copy in a directory named <literal>subv</literal> instead of a directory named <literal>trunk</literal> as we did previously. The directory <literal>subv</literal> will be created if it doesn't already exist."
1836 #: ../source/book.xml:2220
1837 msgid "Disabling Password Caching"
1841 #: ../source/book.xml:2227
1842 msgid "Of course, you're not terribly worried—first because you know that you can't <emphasis>really</emphasis> delete anything from Subversion and, secondly, because your Subversion password isn't the same as any of the other three million passwords you have, right? Right?"
1846 #: ../source/book.xml:2222
1847 msgid "When you perform a Subversion operation that requires you to authenticate, by default Subversion caches your authentication credentials on disk. This is done for convenience, so that you don't have to continually re-enter your password for future operations. If you're concerned about caching your Subversion passwords,<placeholder-1/> you can disable caching either permanently or on a case-by-case basis."
1851 #: ../source/book.xml:2235
1852 msgid "To disable password caching for a particular one-time command, pass the <option>--no-auth-cache</option> option on the commandline. To permanently disable caching, you can add the line <literal>store-passwords = no</literal> to your local machine's Subversion configuration file. See <xref linkend=\"svn.serverconfig.netmodel.credcache\"/> for details."
1856 #: ../source/book.xml:2244
1857 msgid "Authenticating as a Different User"
1861 #: ../source/book.xml:2246
1862 msgid "Since Subversion caches auth credentials by default (both username and password), it conveniently remembers who you were acting as the last time you modified you working copy. But sometimes that's not helpful—particularly if you're working in a shared working copy, like a system configuration directory or a webserver document root. In this case, just pass the <option>--username</option> option on the commandline and Subversion will attempt to authenticate as that user, prompting you for a password if necessary."
1866 #: ../source/book.xml:2262
1867 msgid "Basic Work Cycle"
1871 #: ../source/book.xml:2264
1872 msgid "Subversion has numerous features, options, bells and whistles, but on a day-to-day basis, odds are that you will only use a few of them. In this section we'll run through the most common things that you might find yourself doing with Subversion in the course of a day's work."
1876 #: ../source/book.xml:2269
1877 msgid "The typical work cycle looks like this:"
1881 #: ../source/book.xml:2272
1882 msgid "Update your working copy"
1885 #.(command), (refname)
1886 #: ../source/book.xml:2276 ../source/book.xml:2336 ../source/book.xml:20642
1891 #: ../source/book.xml:2282
1892 msgid "Make changes"
1895 #.(command), (refname)
1896 #: ../source/book.xml:2286 ../source/book.xml:17035
1900 #.(command), (refname)
1901 #: ../source/book.xml:2291 ../source/book.xml:17818
1905 #.(command), (refname)
1906 #: ../source/book.xml:2296 ../source/book.xml:17662
1910 #.(command), (refname)
1911 #: ../source/book.xml:2301 ../source/book.xml:19294
1916 #: ../source/book.xml:2307
1917 msgid "Examine your changes"
1920 #.(command), (refname)
1921 #: ../source/book.xml:2311 ../source/book.xml:20048 ../source/book.xml:24412
1925 #.(command), (refname)
1926 #: ../source/book.xml:2316 ../source/book.xml:3285 ../source/book.xml:17928 ../source/book.xml:24420
1931 #: ../source/book.xml:2322
1932 msgid "Possibly undo some changes"
1935 #.(command), (refname)
1936 #: ../source/book.xml:2326 ../source/book.xml:19942 ../source/book.xml:24428
1941 #: ../source/book.xml:2332
1942 msgid "Resolve Conflicts (Merge Others' Changes)"
1945 #.(command), (refname)
1946 #: ../source/book.xml:2341 ../source/book.xml:19853
1947 msgid "svn resolved"
1951 #: ../source/book.xml:2347
1952 msgid "Commit your changes"
1955 #.(command), (refname)
1956 #: ../source/book.xml:2351 ../source/book.xml:17534
1961 #: ../source/book.xml:2360
1962 msgid "Update Your Working Copy"
1966 #: ../source/book.xml:2362
1967 msgid "When working on a project with a team, you'll want to update your working copy to receive any changes made since your last update by other developers on the project. Use <command>svn update</command> to bring your working copy into sync with the latest revision in the repository."
1971 #: ../source/book.xml:2367
1973 msgid "\n$ svn update\nU foo.c\nU bar.c\nUpdated to revision 2.\n"
1977 #: ../source/book.xml:2373
1978 msgid "In this case, someone else checked in modifications to both <filename>foo.c</filename> and <filename>bar.c</filename> since the last time you updated, and Subversion has updated your working copy to include those changes."
1982 #: ../source/book.xml:2377
1983 msgid "When the server sends changes to your working copy via <command>svn update</command>, a letter code is displayed next to each item to let you know what actions Subversion performed to bring your working copy up-to-date. To find out what these letters mean, see <xref linkend=\"svn.ref.svn.c.update\"/>."
1987 #: ../source/book.xml:2386
1988 msgid "Make Changes to Your Working Copy"
1992 #: ../source/book.xml:2388
1993 msgid "Now you can get to work and make changes in your working copy. It's usually most convenient to decide on a discrete change (or set of changes) to make, such as writing a new feature, fixing a bug, etc. The Subversion commands that you will use here are <command>svn add</command>, <command>svn delete</command>, <command>svn copy</command>, <command>svn move</command>, and <command>svn mkdir</command>. However, if you are merely editing files that are already in Subversion, you may not need to use any of these commands until you commit."
1997 #: ../source/book.xml:2398
1998 msgid "There are two kinds of changes you can make to your working copy: file changes and tree changes. You don't need to tell Subversion that you intend to change a file; just make your changes using your text editor, word processor, graphics program, or whatever tool you would normally use. Subversion automatically detects which files have been changed, and in addition handles binary files just as easily as it handles text files—and just as efficiently too. For tree changes, you can ask Subversion to <quote>mark</quote> files and directories for scheduled removal, addition, copying, or moving. These changes may take place immediately in your working copy, but no additions or removals will happen in the repository until you commit them."
2002 #: ../source/book.xml:2411
2003 msgid "Here is an overview of the five Subversion subcommands that you'll use most often to make tree changes."
2007 #: ../source/book.xml:2415
2008 msgid "Versioning symbolic links"
2012 #: ../source/book.xml:2417
2013 msgid "On non-Windows platforms, Subversion is able to version files of the special type <firstterm>symbolic link</firstterm> (or, <quote>symlink</quote>). A symlink is a file which acts as a sort of transparent reference to some other object in the filesystem, allowing programs to read and write to those objects indirectly by way of performing operations on the symlink itself."
2017 #: ../source/book.xml:2424
2018 msgid "When a symlink is committed into a Subversion repository, Subversion remembers that the file was in fact a symlink, as well as the object to which the symlink <quote>points</quote>. When that symlink is checked out to another working copy on a non-Windows system, Subversion reconstructs a real filesystem-level symbolic link from the versioned symlink. But that doesn't in any way limit the usability of working copies on systems such as Windows which do not support symlinks. On such systems, Subversion simply creates a regular text file whose contents are the path to which to the original symlink pointed. While that file can't be used as a symlink on a Windows system, it also won't prevent Windows users from performing their other Subversion-related activities."
2022 #: ../source/book.xml:2442
2027 #: ../source/book.xml:2445
2028 msgid "Schedule file, directory, or symbolic link <filename>foo</filename> to be added to the repository. When you next commit, <filename>foo</filename> will become a child of its parent directory. Note that if <filename>foo</filename> is a directory, everything underneath <filename>foo</filename> will be scheduled for addition. If you only want to add <filename>foo</filename> itself, pass the <option>--non-recursive (-N)</option> option."
2032 #: ../source/book.xml:2458
2033 msgid "svn delete foo"
2037 #: ../source/book.xml:2470
2038 msgid "Of course, nothing is ever totally deleted from the repository—just from the <literal>HEAD</literal> of the repository. You can get back anything you delete by checking out (or updating your working copy to) a revision earlier than the one in which you deleted it. Also see <xref linkend=\"svn.branchmerge.commonuses.resurrect\"/>."
2042 #: ../source/book.xml:2461
2043 msgid "Schedule file, directory, or symbolic link <filename>foo</filename> to be deleted from the repository. If <filename>foo</filename> is a file or link, it is immediately deleted from your working copy. If <filename>foo</filename> is a directory, it is not deleted, but Subversion schedules it for deletion. When you commit your changes, <filename>foo</filename> will be entirely removed from your working copy and the repository. <placeholder-1/>"
2047 #: ../source/book.xml:2482
2048 msgid "svn copy foo bar"
2052 #: ../source/book.xml:2485
2053 msgid "Create a new item <filename>bar</filename> as a duplicate of <filename>foo</filename> and automatically schedule <filename>bar</filename> for addition. When <filename>bar</filename> is added to the repository on the next commit, its copy history is recorded (as having originally come from <filename>foo</filename>). <command>svn copy</command> does not create intermediate directories."
2057 #: ../source/book.xml:2497
2058 msgid "svn move foo bar"
2062 #: ../source/book.xml:2500
2063 msgid "This command is exactly the same as running <command>svn copy foo bar; svn delete foo</command>. That is, <filename>bar</filename> is scheduled for addition as a copy of <filename>foo</filename>, and <filename>foo</filename> is scheduled for removal. <command>svn move</command> does not create intermediate directories."
2067 #: ../source/book.xml:2511
2068 msgid "svn mkdir blort"
2072 #: ../source/book.xml:2514
2073 msgid "This command is exactly the same as running <command>mkdir blort; svn add blort</command>. That is, a new directory named <filename>blort</filename> is created and scheduled for addition."
2077 #: ../source/book.xml:2523
2078 msgid "Changing the Repository Without a Working Copy"
2082 #: ../source/book.xml:2525
2083 msgid "There <emphasis>are</emphasis> some use cases that immediately commit tree changes to the repository. This only happens when a subcommand is operating directly on a URL, rather than on a working-copy path. In particular, specific uses of <command>svn mkdir</command>, <command>svn copy</command>, <command>svn move</command>, and <command>svn delete</command> can work with URLs (And don't forget that <command>svn import</command> always makes changes to a URL)."
2087 #: ../source/book.xml:2534
2088 msgid "URL operations behave in this manner because commands that operate on a working copy can use the working copy as a sort of <quote>staging area</quote> to set up your changes before committing them to the repository. Commands that operate on URLs don't have this luxury, so when you operate directly on a URL, any of the above actions represent an immediate commit."
2092 #: ../source/book.xml:2546
2093 msgid "Examine Your Changes"
2097 #: ../source/book.xml:2548
2098 msgid "Once you've finished making changes, you need to commit them to the repository, but before you do so, it's usually a good idea to take a look at exactly what you've changed. By examining your changes before you commit, you can make a more accurate log message. You may also discover that you've inadvertently changed a file, and this gives you a chance to revert those changes before committing. Additionally, this is a good opportunity to review and scrutinize changes before publishing them. You can see an overview of the changes you've made by using <command>svn status</command>, and dig into the details of those changes by using <command>svn diff</command>."
2102 #: ../source/book.xml:2562
2103 msgid "Look Ma! No Network!"
2107 #: ../source/book.xml:2571
2108 msgid "And also that you don't have a WAN card. Thought you got us, huh?"
2112 #: ../source/book.xml:2564
2113 msgid "The commands <command>svn status</command>, <command>svn diff</command>, and <command>svn revert</command> can be used without any network access even if your repository <emphasis>is</emphasis> across the network. This makes it easy to manage your changes-in-progress when you are somewhere without a network connection, such as travelling on an airplane, riding a commuter train or hacking on the beach.<placeholder-1/>"
2117 #: ../source/book.xml:2574
2118 msgid "Subversion does this by keeping private caches of pristine versions of each versioned file inside of the <filename>.svn</filename> administrative areas. This allows Subversion to report—and revert—local modifications to those files <emphasis>without network access</emphasis>. This cache (called the <quote>text-base</quote>) also allows Subversion to send the user's local modifications during a commit to the server as a compressed <firstterm>delta</firstterm> (or <quote>difference</quote>) against the pristine version. Having this cache is a tremendous benefit—even if you have a fast net connection, it's much faster to send only a file's changes rather than the whole file to the server."
2122 #: ../source/book.xml:2589
2123 msgid "Subversion has been optimized to help you with this task, and is able to do many things without communicating with the repository. In particular, your working copy contains a hidden cached <quote>pristine</quote> copy of each version controlled file within the <filename>.svn</filename> area. Because of this, Subversion can quickly show you how your working files have changed, or even allow you to undo your changes without contacting the repository."
2127 #: ../source/book.xml:2600
2128 msgid "See an overview of your changes"
2132 #: ../source/book.xml:2602
2133 msgid "To get an overview of your changes, you'll use the <command>svn status</command> command. You'll probably use <command>svn status</command> more than any other Subversion command."
2137 #: ../source/book.xml:2608
2138 msgid "CVS Users: Hold That Update!"
2142 #: ../source/book.xml:2610
2143 msgid "You're probably used to using <command>cvs update</command> to see what changes you've made to your working copy. <command>svn status</command> will give you all the information you need regarding what has changed in your working copy—without accessing the repository or potentially incorporating new changes published by other users."
2147 #: ../source/book.xml:2617
2148 msgid "In Subversion, <command>update</command> does just that—it updates your working copy with any changes committed to the repository since the last time you've updated your working copy. You may have to break the habit of using the <command>update</command> command to see what local modifications you've made."
2152 #: ../source/book.xml:2624
2153 msgid "If you run <command>svn status</command> at the top of your working copy with no arguments, it will detect all file and tree changes you've made. Below are a few examples of the most common status codes that <command>svn status</command> can return. (Note that the text following <literal>#</literal> is not actually printed by <command>svn status</command>.)"
2157 #: ../source/book.xml:2631
2159 msgid "\nA stuff/loot/bloo.h # file is scheduled for addition\nC stuff/loot/lump.c # file has textual conflicts from an update\nD stuff/fish.c # file is scheduled for deletion\nM bar.c # the content in bar.c has local modifications\n"
2163 #: ../source/book.xml:2637
2164 msgid "In this output format <command>svn status</command> prints six columns of characters, followed by several whitespace characters, followed by a file or directory name. The first column tells the status of a file or directory and/or its contents. The codes we listed are:"
2168 #: ../source/book.xml:2645
2174 #: ../source/book.xml:2648
2175 msgid "The file, directory, or symbolic link <filename>item</filename> has been scheduled for addition into the repository."
2179 #: ../source/book.xml:2655
2185 #: ../source/book.xml:2658
2186 msgid "The file <filename>item</filename> is in a state of conflict. That is, changes received from the server during an update overlap with local changes that you have in your working copy. You must resolve this conflict before committing your changes to the repository."
2190 #: ../source/book.xml:2668
2196 #: ../source/book.xml:2671
2197 msgid "The file, directory, or symbolic link <filename>item</filename> has been scheduled for deletion from the repository."
2201 #: ../source/book.xml:2678
2207 #: ../source/book.xml:2681
2208 msgid "The contents of the file <filename>item</filename> have been modified."
2212 #: ../source/book.xml:2686
2213 msgid "If you pass a specific path to <command>svn status</command>, you get information about that item alone:"
2217 #: ../source/book.xml:2689
2219 msgid "\n$ svn status stuff/fish.c\nD stuff/fish.c\n"
2223 #: ../source/book.xml:2693
2224 msgid "<command>svn status</command> also has a <option>--verbose (-v)</option> option, which will show you the status of <emphasis>every</emphasis> item in your working copy, even if it has not been changed:"
2228 #: ../source/book.xml:2697
2230 msgid "\n$ svn status -v\nM 44 23 sally README\n 44 30 sally INSTALL\nM 44 20 harry bar.c\n 44 18 ira stuff\n 44 35 harry stuff/trout.c\nD 44 19 ira stuff/fish.c\n 44 21 sally stuff/things\nA 0 ? ? stuff/things/bloo.h\n 44 36 harry stuff/things/gloo.c\n"
2234 #: ../source/book.xml:2709
2235 msgid "This is the <quote>long form</quote> output of <command>svn status</command>. The letters in the first column mean the same as before, but the second column shows the working-revision of the item. The third and fourth columns show the revision in which the item last changed, and who changed it."
2239 #: ../source/book.xml:2715
2240 msgid "None of the prior invocations to <command>svn status</command> contact the repository—instead, they compare the metadata in the <filename>.svn</filename> directory with the working copy. Finally, there is the <option>--show-updates (-u)</option> option, which contacts the repository and adds information about things that are out-of-date:"
2244 #: ../source/book.xml:2722
2246 msgid "\n$ svn status -u -v\nM * 44 23 sally README\nM 44 20 harry bar.c\n * 44 35 harry stuff/trout.c\nD 44 19 ira stuff/fish.c\nA 0 ? ? stuff/things/bloo.h\nStatus against revision: 46\n"
2250 #: ../source/book.xml:2731
2251 msgid "Notice the two asterisks: if you were to run <command>svn update</command> at this point, you would receive changes to <filename>README</filename> and <filename>trout.c</filename>. This tells you some very useful information—you'll need to update and get the server changes on <filename>README</filename> before you commit, or the repository will reject your commit for being out-of-date. (More on this subject later.)"
2255 #: ../source/book.xml:2739
2256 msgid "<command>svn status</command> can display much more information about the files and directories in your working copy than we've shown here—for an exhaustive description of svn status and its output, see <xref linkend=\"svn.ref.svn.c.status\"/>."
2260 #: ../source/book.xml:2747
2261 msgid "Examine the details of your local modifications"
2265 #: ../source/book.xml:2749
2266 msgid "Another way to examine your changes is with the <command>svn diff</command> command. You can find out <emphasis>exactly</emphasis> how you've modified things by running <command>svn diff</command> with no arguments, which prints out file changes in <firstterm>unified diff format</firstterm>:"
2270 #: ../source/book.xml:2755
2272 msgid "\n$ svn diff\nIndex: bar.c\n===================================================================\n--- bar.c\t(revision 3)\n+++ bar.c\t(working copy)\n@@ -1,7 +1,12 @@\n+#include <sys/types.h>\n+#include <sys/stat.h>\n+#include <unistd.h>\n+\n+#include <stdio.h>\n\n int main(void) {\n- printf(\"Sixty-four slices of American Cheese...\\n\");\n+ printf(\"Sixty-five slices of American Cheese...\\n\");\n return 0;\n }\n\nIndex: README\n===================================================================\n--- README\t(revision 3)\n+++ README\t(working copy)\n@@ -193,3 +193,4 @@\n+Note to self: pick up laundry.\n\nIndex: stuff/fish.c\n===================================================================\n--- stuff/fish.c\t(revision 1)\n+++ stuff/fish.c\t(working copy)\n-Welcome to the file known as 'fish'.\n-Information on fish will be here soon.\n\nIndex: stuff/things/bloo.h\n===================================================================\n--- stuff/things/bloo.h\t(revision 8)\n+++ stuff/things/bloo.h\t(working copy)\n+Here is a new file to describe\n+things about bloo.\n"
2276 #: ../source/book.xml:2795
2277 msgid "The <command>svn diff</command> command produces this output by comparing your working files against the cached <quote>pristine</quote> copies within the <filename>.svn</filename> area. Files scheduled for addition are displayed as all added-text, and files scheduled for deletion are displayed as all deleted text."
2281 #: ../source/book.xml:2802
2282 msgid "Output is displayed in unified diff format. That is, removed lines are prefaced with <literal>-</literal> and added lines are prefaced with <literal>+</literal>. <command>svn diff</command> also prints filename and offset information useful to the <command>patch</command> program, so you can generate <quote>patches</quote> by redirecting the diff output to a file:"
2286 #: ../source/book.xml:2810
2288 msgid "\n$ svn diff > patchfile\n"
2292 #: ../source/book.xml:2813
2293 msgid "You could, for example, email the patch file to another developer for review or testing prior to commit."
2297 #: ../source/book.xml:2815
2298 msgid "Subversion uses its internal diff engine, which produces unified diff format, by default. If you want diff output in a different format, specify an external diff program using <option>--diff-cmd</option> and pass any flags you'd like to it using the <option>--extensions (-x)</option> option. For example, to see local differences in file <filename>foo.c</filename> in context output format while ignoring case differences, you might run <command>svn diff --diff-cmd /usr/bin/diff --extensions '-i' foo.c</command>."
2302 #: ../source/book.xml:2830
2303 msgid "Undoing Working Changes"
2307 #: ../source/book.xml:2832
2308 msgid "Suppose while viewing the output of <command>svn diff</command> you determine that all the changes you made to a particular file are mistakes. Maybe you shouldn't have changed the file at all, or perhaps it would be easier to make different changes starting from scratch."
2312 #: ../source/book.xml:2837
2313 msgid "This is a perfect opportunity to use <command>svn revert</command>:"
2317 #: ../source/book.xml:2839
2319 msgid "\n$ svn revert README\nReverted 'README'\n"
2323 #: ../source/book.xml:2843
2324 msgid "Subversion reverts the file to its pre-modified state by overwriting it with the cached <quote>pristine</quote> copy from the <filename>.svn</filename> area. But also note that <command>svn revert</command> can undo <emphasis>any</emphasis> scheduled operations—for example, you might decide that you don't want to add a new file after all:"
2328 #: ../source/book.xml:2850
2330 msgid "\n$ svn status foo\n? foo\n\n$ svn add foo\nA foo\n\n$ svn revert foo\nReverted 'foo'\n\n$ svn status foo\n? foo\n"
2334 #: ../source/book.xml:2864
2335 msgid "<command>svn revert</command><replaceable>ITEM</replaceable> has exactly the same effect as deleting <replaceable>ITEM</replaceable> from your working copy and then running <command>svn update -r BASE</command><replaceable>ITEM</replaceable>. However, if you're reverting a file, <command>svn revert</command> has one very noticeable difference—it doesn't have to communicate with the repository to restore your file."
2339 #: ../source/book.xml:2873
2340 msgid "Or perhaps you mistakenly removed a file from version control:"
2344 #: ../source/book.xml:2875
2346 msgid "\n$ svn status README\n README\n\n$ svn delete README\nD README\n\n$ svn revert README\nReverted 'README'\n\n$ svn status README\n README\n"
2350 #: ../source/book.xml:2892
2351 msgid "Resolve Conflicts (Merging Others' Changes)"
2355 #: ../source/book.xml:2894
2356 msgid "We've already seen how <command>svn status -u</command> can predict conflicts. Suppose you run <command>svn update</command> and some interesting things occur:"
2360 #: ../source/book.xml:2897
2362 msgid "\n$ svn update\nU INSTALL\nG README\nC bar.c\nUpdated to revision 46.\n"
2366 #: ../source/book.xml:2904
2367 msgid "The <computeroutput>U</computeroutput> and <computeroutput>G</computeroutput> codes are no cause for concern; those files cleanly absorbed changes from the repository. The files marked with <computeroutput>U</computeroutput> contained no local changes but were <computeroutput>U</computeroutput>pdated with changes from the repository. The <computeroutput>G</computeroutput> stands for mer<computeroutput>G</computeroutput>ed, which means that the file had local changes to begin with, but the changes coming from the repository didn't overlap with the local changes."
2371 #: ../source/book.xml:2915
2372 msgid "But the <computeroutput>C</computeroutput> stands for <computeroutput>c</computeroutput>onflict. This means that the changes from the server overlapped with your own, and now you have to manually choose between them."
2376 #: ../source/book.xml:2919
2377 msgid "Whenever a conflict occurs, three things typically occur to assist you in noticing and resolving that conflict:"
2381 #: ../source/book.xml:2923
2382 msgid "Subversion prints a <computeroutput>C</computeroutput> during the update, and remembers that the file is in a state of conflict."
2386 #: ../source/book.xml:2928
2387 msgid "If Subversion considers the file to be mergeable, it places <firstterm>conflict markers</firstterm>—special strings of text which delimit the <quote>sides</quote> of the conflict—into the file to visibly demonstrate the overlapping areas. (Subversion uses the <literal>svn:mime-type</literal> property to decide if a file is capable of contextual, line-based merging. See <xref linkend=\"svn.advanced.props.special.mime-type\"/> to learn more.)"
2391 #: ../source/book.xml:2939
2392 msgid "For every conflicted file, Subversion places three extra unversioned files in your working copy:"
2396 #: ../source/book.xml:2944
2397 msgid "filename.mine"
2401 #: ../source/book.xml:2947
2402 msgid "This is your file as it existed in your working copy before you updated your working copy—that is, without conflict markers. This file has only your latest changes in it. (If Subversion considers the file to be unmergeable, then the <filename>.mine</filename> file isn't created, since it would be identical to the working file.)"
2406 #: ../source/book.xml:2958
2407 msgid "filename.rOLDREV"
2411 #: ../source/book.xml:2961
2412 msgid "This is the file that was the <literal>BASE</literal> revision before you updated your working copy. That is, the file that you checked out before you made your latest edits."
2416 #: ../source/book.xml:2970
2417 msgid "filename.rNEWREV"
2421 #: ../source/book.xml:2973
2422 msgid "This is the file that your Subversion client just received from the server when you updated your working copy. This file corresponds to the <literal>HEAD</literal> revision of the repository."
2426 #: ../source/book.xml:2981
2427 msgid "Here <literal>OLDREV</literal> is the revision number of the file in your <filename>.svn</filename> directory and <literal>NEWREV</literal> is the revision number of the repository <literal>HEAD</literal>."
2431 #: ../source/book.xml:2987
2432 msgid "For example, Sally makes changes to the file <filename>sandwich.txt</filename> in the repository. Harry has just changed the file in his working copy and checked it in. Sally updates her working copy before checking in and she gets a conflict:"
2436 #: ../source/book.xml:2992
2438 msgid "\n$ svn update\nC sandwich.txt\nUpdated to revision 2.\n$ ls -1\nsandwich.txt\nsandwich.txt.mine\nsandwich.txt.r1\nsandwich.txt.r2\n"
2442 #: ../source/book.xml:3002
2443 msgid "At this point, Subversion will <emphasis>not</emphasis> allow you to commit the file <filename>sandwich.txt</filename> until the three temporary files are removed."
2447 #: ../source/book.xml:3005
2449 msgid "\n$ svn commit -m \"Add a few more things\"\nsvn: Commit failed (details follow):\nsvn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict\n"
2453 #: ../source/book.xml:3010
2454 msgid "If you get a conflict, you need to do one of three things:"
2458 #: ../source/book.xml:3014
2459 msgid "Merge the conflicted text <quote>by hand</quote> (by examining and editing the conflict markers within the file)."
2463 #: ../source/book.xml:3019
2464 msgid "Copy one of the temporary files on top of your working file."
2468 #: ../source/book.xml:3023
2469 msgid "Run <command>svn revert <filename></command> to throw away all of your local changes."
2473 #: ../source/book.xml:3031
2474 msgid "You can always remove the temporary files yourself, but would you really want to do that when Subversion can do it for you? We didn't think so."
2478 #: ../source/book.xml:3027
2479 msgid "Once you've resolved the conflict, you need to let Subversion know by running <command>svn resolved</command>. This removes the three temporary files and Subversion no longer considers the file to be in a state of conflict.<placeholder-1/>"
2483 #: ../source/book.xml:3034
2485 msgid "\n$ svn resolved sandwich.txt\nResolved conflicted state of 'sandwich.txt'\n"
2489 #: ../source/book.xml:3041
2490 msgid "Merging Conflicts by Hand"
2494 #: ../source/book.xml:3043
2495 msgid "Merging conflicts by hand can be quite intimidating the first time you attempt it, but with a little practice, it can become as easy as falling off a bike."
2499 #: ../source/book.xml:3046
2500 msgid "Here's an example. Due to a miscommunication, you and Sally, your collaborator, both edit the file <filename>sandwich.txt</filename> at the same time. Sally commits her changes, and when you go to update your working copy, you get a conflict and you're going to have to edit <filename>sandwich.txt</filename> to resolve the conflicts. First, let's take a look at the file:"
2504 #: ../source/book.xml:3053
2506 msgid "\n$ cat sandwich.txt\nTop piece of bread\nMayonnaise\nLettuce\nTomato\nProvolone\n<<<<<<< .mine\nSalami\nMortadella\nProsciutto\n=======\nSauerkraut\nGrilled Chicken\n>>>>>>> .r2\nCreole Mustard\nBottom piece of bread\n"
2510 #: ../source/book.xml:3071
2511 msgid "The strings of less-than signs, equal signs, and greater-than signs are conflict markers, and are not part of the actual data in conflict. You generally want to ensure that those are removed from the file before your next commit. The text between the first two sets of markers is composed of the changes you made in the conflicting area:"
2515 #: ../source/book.xml:3078
2517 msgid "\n<<<<<<< .mine\nSalami\nMortadella\nProsciutto\n=======\n"
2521 #: ../source/book.xml:3085
2522 msgid "The text between the second and third sets of conflict markers is the text from Sally's commit:"
2526 #: ../source/book.xml:3087
2528 msgid "\n=======\nSauerkraut\nGrilled Chicken\n>>>>>>> .r2\n"
2532 #: ../source/book.xml:3098
2533 msgid "And if you ask them for it, they may very well ride you out of town on a rail."
2537 #: ../source/book.xml:3093
2538 msgid "Usually you won't want to just delete the conflict markers and Sally's changes—she's going to be awfully surprised when the sandwich arrives and it's not what she wanted. So this is where you pick up the phone or walk across the office and explain to Sally that you can't get sauerkraut from an Italian deli.<placeholder-1/> Once you've agreed on the changes you will check in, edit your file and remove the conflict markers."
2542 #: ../source/book.xml:3103
2544 msgid "\nTop piece of bread\nMayonnaise\nLettuce\nTomato\nProvolone\nSalami\nMortadella\nProsciutto\nCreole Mustard\nBottom piece of bread\n"
2548 #: ../source/book.xml:3115
2549 msgid "Now run <command>svn resolved</command>, and you're ready to commit your changes:"
2553 #: ../source/book.xml:3117
2555 msgid "\n$ svn resolved sandwich.txt\n$ svn commit -m \"Go ahead and use my sandwich, discarding Sally's edits.\"\n"
2559 #: ../source/book.xml:3121
2560 msgid "Note that <command>svn resolved</command>, unlike most of the other commands we deal with in this chapter, requires an argument. In any case, you want to be careful and only run <command>svn resolved</command> when you're certain that you've fixed the conflict in your file—once the temporary files are removed, Subversion will let you commit the file even if it still contains conflict markers."
2564 #: ../source/book.xml:3128
2565 msgid "If you ever get confused while editing the conflicted file, you can always consult the three files that Subversion creates for you in your working copy—including your file as it was before you updated. You can even use a third-party interactive merging tool to examine those three files."
2569 #: ../source/book.xml:3138
2570 msgid "Copying a File Onto Your Working File"
2574 #: ../source/book.xml:3140
2575 msgid "If you get a conflict and decide that you want to throw out your changes, you can merely copy one of the temporary files created by Subversion over the file in your working copy:"
2579 #: ../source/book.xml:3144
2581 msgid "\n$ svn update\nC sandwich.txt\nUpdated to revision 2.\n$ ls sandwich.*\nsandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1\n$ cp sandwich.txt.r2 sandwich.txt\n$ svn resolved sandwich.txt\n"
2585 #: ../source/book.xml:3157
2586 msgid "Punting: Using <command>svn revert</command>"
2590 #: ../source/book.xml:3159
2591 msgid "If you get a conflict, and upon examination decide that you want to throw out your changes and start your edits again, just revert your changes:"
2595 #: ../source/book.xml:3162
2597 msgid "\n$ svn revert sandwich.txt\nReverted 'sandwich.txt'\n$ ls sandwich.*\nsandwich.txt\n"
2601 #: ../source/book.xml:3168
2602 msgid "Note that when you revert a conflicted file, you don't have to run <command>svn resolved</command>."
2606 #: ../source/book.xml:3175
2607 msgid "Commit Your Changes"
2611 #: ../source/book.xml:3177
2612 msgid "Finally! Your edits are finished, you've merged all changes from the server, and you're ready to commit your changes to the repository."
2616 #: ../source/book.xml:3180
2617 msgid "The <command>svn commit</command> command sends all of your changes to the repository. When you commit a change, you need to supply a <firstterm>log message</firstterm>, describing your change. Your log message will be attached to the new revision you create. If your log message is brief, you may wish to supply it on the command line using the <option>--message</option> (or <option>-m</option>) option:"
2621 #: ../source/book.xml:3188
2623 msgid "\n$ svn commit -m \"Corrected number of cheese slices.\"\nSending sandwich.txt\nTransmitting file data .\nCommitted revision 3.\n"
2627 #: ../source/book.xml:3194
2628 msgid "However, if you've been composing your log message as you work, you may want to tell Subversion to get the message from a file by passing the filename with the <option>--file (-F)</option> option:"
2632 #: ../source/book.xml:3198
2634 msgid "\n$ svn commit -F logmsg\nSending sandwich.txt\nTransmitting file data .\nCommitted revision 4.\n"
2638 #: ../source/book.xml:3204
2639 msgid "If you fail to specify either the <option>--message</option> or <option>--file</option> option, then Subversion will automatically launch your favorite editor (see the <literal>editor-cmd</literal> section in <xref linkend=\"svn.advanced.confarea.opts.config\"/>) for composing a log message."
2643 #: ../source/book.xml:3211
2644 msgid "If you're in your editor writing a commit message and decide that you want to cancel your commit, you can just quit your editor without saving changes. If you've already saved your commit message, simply delete the text, save again, then abort."
2648 #: ../source/book.xml:3216
2650 msgid "\n$ svn commit\nWaiting for Emacs...Done\n\nLog message unchanged or not specified\na)bort, c)ontinue, e)dit\na\n$\n"
2654 #: ../source/book.xml:3226
2655 msgid "The repository doesn't know or care if your changes make any sense as a whole; it only checks to make sure that nobody else has changed any of the same files that you did when you weren't looking. If somebody <emphasis>has</emphasis> done that, the entire commit will fail with a message informing you that one or more of your files is out-of-date:"
2659 #: ../source/book.xml:3232
2661 msgid "\n$ svn commit -m \"Add another rule\"\nSending rules.txt\nsvn: Commit failed (details follow):\nsvn: Your file or directory 'sandwich.txt' is probably out-of-date\n…\n"
2665 #: ../source/book.xml:3239
2666 msgid "(The exact wording of this error message depends on the network protocol and server you're using, but the idea is the same in all cases.)"
2670 #: ../source/book.xml:3242
2671 msgid "At this point, you need to run <command>svn update</command>, deal with any merges or conflicts that result, and attempt your commit again."
2675 #: ../source/book.xml:3245
2676 msgid "That covers the basic work cycle for using Subversion. There are many other features in Subversion that you can use to manage your repository and working copy, but most of your day-to-day use of Subversion will involve only the commands that we've discussed so far in this chapter. We will, however, cover a few more commands that you'll use fairly often."
2680 #: ../source/book.xml:3259
2681 msgid "Examining History"
2685 #: ../source/book.xml:3261
2686 msgid "Your Subversion repository is like a time machine. It keeps a record of every change ever committed, and allows you to explore this history by examining previous versions of files and directories as well as the metadata that accompanies them. With a single Subversion command, you can check out the repository (or restore an existing working copy) exactly as it was at any date or revision number in the past. However, sometimes you just want to <emphasis>peer into</emphasis> the past instead of <emphasis>going into</emphasis> the past."
2690 #: ../source/book.xml:3270
2691 msgid "There are several commands that can provide you with historical data from the repository:"
2694 #.(command), (refname)
2695 #: ../source/book.xml:3275 ../source/book.xml:18863
2700 #: ../source/book.xml:3278
2701 msgid "Shows you broad information: log messages with date and author information attached to revisions, and which paths changed in each revision."
2705 #: ../source/book.xml:3288
2706 msgid "Shows line-level details of a particular change."
2709 #.(command), (refname)
2710 #: ../source/book.xml:3293 ../source/book.xml:3547 ../source/book.xml:17242
2715 #: ../source/book.xml:3296
2716 msgid "Retrieves a file as it existed in a particular revision number and display it on your screen."
2719 #.(command), (refname)
2720 #: ../source/book.xml:3302 ../source/book.xml:3572 ../source/book.xml:18651
2725 #: ../source/book.xml:3305
2726 msgid "Displays the files in a directory for any given revision."
2730 #: ../source/book.xml:3313
2731 msgid "Generating a list of historical changes"
2735 #: ../source/book.xml:3315
2736 msgid "To find information about the history of a file or directory, use the <command>svn log</command> command. <command>svn log</command> will provide you with a record of who made changes to a file or directory, at what revision it changed, the time and date of that revision, and, if it was provided, the log message that accompanied the commit."
2740 #: ../source/book.xml:3322
2742 msgid "\n$ svn log\n------------------------------------------------------------------------\nr3 | sally | Mon, 15 Jul 2002 18:03:46 -0500 | 1 line\n\nAdded include lines and corrected # of cheese slices.\n------------------------------------------------------------------------\nr2 | harry | Mon, 15 Jul 2002 17:47:57 -0500 | 1 line\n\nAdded main() methods.\n------------------------------------------------------------------------\nr1 | sally | Mon, 15 Jul 2002 17:40:08 -0500 | 1 line\n\nInitial import\n------------------------------------------------------------------------\n"
2746 #: ../source/book.xml:3338
2747 msgid "Note that the log messages are printed in <emphasis>reverse chronological order</emphasis> by default. If you wish to see a different range of revisions in a particular order, or just a single revision, pass the <option>--revision (-r)</option> option:"
2751 #: ../source/book.xml:3343
2753 msgid "\n$ svn log -r 5:19 # shows logs 5 through 19 in chronological order\n\n$ svn log -r 19:5 # shows logs 5 through 19 in reverse order\n\n$ svn log -r 8 # shows log for revision 8\n"
2757 #: ../source/book.xml:3350
2758 msgid "You can also examine the log history of a single file or directory. For example:"
2762 #: ../source/book.xml:3352
2764 msgid "\n$ svn log foo.c\n…\n$ svn log http://foo.com/svn/trunk/code/foo.c\n…\n"
2768 #: ../source/book.xml:3358
2769 msgid "These will display log messages <emphasis>only</emphasis> for those revisions in which the working file (or URL) changed."
2773 #: ../source/book.xml:3361
2774 msgid "If you want even more information about a file or directory, <command>svn log</command> also takes a <option>--verbose (-v)</option> option. Because Subversion allows you to move and copy files and directories, it is important to be able to track path changes in the filesystem, so in verbose mode, <command>svn log</command> will include a list of changed paths in a revision in its output:"
2778 #: ../source/book.xml:3368
2780 msgid "\n$ svn log -r 8 -v\n------------------------------------------------------------------------\nr8 | sally | 2002-07-14 08:15:29 -0500 | 1 line\nChanged paths:\nM /trunk/code/foo.c\nM /trunk/code/bar.h\nA /trunk/code/doc/README\n\nFrozzled the sub-space winch.\n\n------------------------------------------------------------------------\n"
2784 #: ../source/book.xml:3381
2785 msgid "<command>svn log</command> also takes a <option>--quiet</option> (<option>-q</option>) option, which suppresses the body of the log message. When combined with <option>--verbose</option>, it gives just the names of the changed files."
2789 #: ../source/book.xml:3387
2790 msgid "Why Does <command>svn log</command> Give Me an Empty Response?"
2794 #: ../source/book.xml:3390
2795 msgid "After working with Subversion for a bit, most users will come across something like this:"
2799 #: ../source/book.xml:3392
2801 msgid "\n$ svn log -r 2\n------------------------------------------------------------------------\n$\n"
2805 #: ../source/book.xml:3397
2806 msgid "At first glance, this seems like an error. But recall that while revisions are repository-wide, <command>svn log</command> operates on a path in the repository. If you supply no path, Subversion uses the current working directory as the default target. As a result, if you're operating in a subdirectory of your working copy and attempt to see the log of a revision in which neither that directory nor any of its children was changed, Subversion will show you an empty log. If you want to see what changed in that revision, try pointing <command>svn log</command> directly at the top-most URL of your repository, as in <command>svn log -r 2 http://svn.collab.net/repos/svn</command>."
2810 #: ../source/book.xml:3414
2811 msgid "Examining the details of historical changes"
2815 #: ../source/book.xml:3416
2816 msgid "We've already seen <command>svn diff</command> before—it displays file differences in unified diff format; it was used to show the local modifications made to our working copy before committing to the repository."
2820 #: ../source/book.xml:3420
2821 msgid "In fact, it turns out that there are <emphasis>three</emphasis> distinct uses of <command>svn diff</command>:"
2825 #: ../source/book.xml:3425
2826 msgid "Examining local changes"
2830 #: ../source/book.xml:3428
2831 msgid "Comparing your working copy to the repository"
2835 #: ../source/book.xml:3431
2836 msgid "Comparing repository to repository"
2840 #: ../source/book.xml:3437
2841 msgid "Examining Local Changes"
2845 #: ../source/book.xml:3439
2846 msgid "As we've seen, invoking <command>svn diff</command> with no options will compare your working files to the cached <quote>pristine</quote> copies in the <filename>.svn</filename> area:"
2850 #: ../source/book.xml:3443
2852 msgid "\n$ svn diff\nIndex: rules.txt\n===================================================================\n--- rules.txt\t(revision 3)\n+++ rules.txt\t(working copy)\n@@ -1,4 +1,5 @@\n Be kind to others\n Freedom = Responsibility\n Everything in moderation\n-Chew with your mouth open\n+Chew with your mouth closed\n+Listen when others are speaking\n$\n"
2856 #: ../source/book.xml:3462
2857 msgid "Comparing Working Copy to Repository"
2861 #: ../source/book.xml:3464
2862 msgid "If a single <option>--revision</option> (<option>-r</option>) number is passed, then your working copy is compared to the specified revision in the repository."
2866 #: ../source/book.xml:3468
2868 msgid "\n$ svn diff -r 3 rules.txt\nIndex: rules.txt\n===================================================================\n--- rules.txt\t(revision 3)\n+++ rules.txt\t(working copy)\n@@ -1,4 +1,5 @@\n Be kind to others\n Freedom = Responsibility\n Everything in moderation\n-Chew with your mouth open\n+Chew with your mouth closed\n+Listen when others are speaking\n$\n"
2872 #: ../source/book.xml:3487
2873 msgid "Comparing Repository to Repository"
2877 #: ../source/book.xml:3489
2878 msgid "If two revision numbers, separated by a colon, are passed via <option>--revision (-r)</option>, then the two revisions are directly compared."
2882 #: ../source/book.xml:3492
2884 msgid "\n$ svn diff -r 2:3 rules.txt\nIndex: rules.txt\n===================================================================\n--- rules.txt\t(revision 2)\n+++ rules.txt\t(revision 3)\n@@ -1,4 +1,4 @@\n Be kind to others\n-Freedom = Chocolate Ice Cream\n+Freedom = Responsibility\n Everything in moderation\n Chew with your mouth open\n$\n"
2888 #: ../source/book.xml:3506
2889 msgid "A more convenient way of comparing a revision to the previous revision is to use the <option>--change (-c)</option>:"
2893 #: ../source/book.xml:3509
2895 msgid "\n$ svn diff -c 3 rules.txt\nIndex: rules.txt\n===================================================================\n--- rules.txt\t(revision 2)\n+++ rules.txt\t(revision 3)\n@@ -1,4 +1,4 @@\n Be kind to others\n-Freedom = Chocolate Ice Cream\n+Freedom = Responsibility\n Everything in moderation\n Chew with your mouth open\n$\n"
2899 #: ../source/book.xml:3523
2900 msgid "Lastly, you can compare repository revisions even when you don't have a working copy on your local machine, just by including the appropriate URL on the command line:"
2904 #: ../source/book.xml:3526
2906 msgid "\n$ svn diff -c 5 http://svn.example.com/repos/example/trunk/text/rules.txt\n…\n$\n"
2910 #: ../source/book.xml:3536
2911 msgid "Browsing the repository"
2915 #: ../source/book.xml:3538
2916 msgid "Using <command>svn cat</command> and <command>svn list</command>, you can view various revisions of files and directories without changing the working revision of your working copy. In fact, you don't even need a working copy to use either one."
2920 #: ../source/book.xml:3550
2921 msgid "If you want to examine an earlier version of a file and not necessarily the differences between two files, you can use <command>svn cat</command>:"
2925 #: ../source/book.xml:3553
2927 msgid "\n$ svn cat -r 2 rules.txt\nBe kind to others\nFreedom = Chocolate Ice Cream\nEverything in moderation\nChew with your mouth open\n$\n"
2931 #: ../source/book.xml:3561
2932 msgid "You can also redirect the output directly into a file:"
2936 #: ../source/book.xml:3563
2938 msgid "\n$ svn cat -r 2 rules.txt > rules.txt.v2\n$\n"
2942 #: ../source/book.xml:3575
2943 msgid "The <command>svn list</command> command shows you what files are in a repository directory without actually downloading the files to your local machine:"
2947 #: ../source/book.xml:3578
2949 msgid "\n$ svn list http://svn.collab.net/repos/svn\nREADME\nbranches/\nclients/\ntags/\ntrunk/\n"
2953 #: ../source/book.xml:3586
2954 msgid "If you want a more detailed listing, pass the <option>--verbose (-v)</option> flag to get output like this:"
2958 #: ../source/book.xml:3589
2960 msgid "\n$ svn list -v http://svn.collab.net/repos/svn\n 20620 harry 1084 Jul 13 2006 README\n 23339 harry Feb 04 01:40 branches/\n 21282 sally Aug 27 09:41 developer-resources/\n 23198 harry Jan 23 17:17 tags/\n 23351 sally Feb 05 13:26 trunk/\n"
2964 #: ../source/book.xml:3597
2965 msgid "The columns tell you the revision at which the file or directory was last modified, the user who modified it, the size if it is a file, the date it was last modified, and the item's name."
2969 #: ../source/book.xml:3602
2970 msgid "The <command>svn list</command> with no arguments defaults to the <emphasis>repository URL</emphasis> of the current working directory, <emphasis>not</emphasis> the local working copy directory. After all, if you wanted a listing of your local directory, you could use just plain <command>ls</command> (or any reasonable non-Unixy equivalent)."
2974 #: ../source/book.xml:3615
2975 msgid "Fetching older repository snapshots"
2979 #: ../source/book.xml:3621
2980 msgid "See? We told you that Subversion was a time machine."
2984 #: ../source/book.xml:3617
2985 msgid "In addition to all of the above commands, you can use <command>svn update</command> and <command>svn checkout</command> with the <option>--revision</option> option to take an entire working copy <quote>back in time</quote><placeholder-1/>:"
2989 #: ../source/book.xml:3623
2991 msgid "\n$ svn checkout -r 1729 # Checks out a new working copy at r1729\n…\n$ svn update -r 1729 # Updates an existing working copy to r1729\n…\n"
2995 #: ../source/book.xml:3630
2996 msgid "Many Subversion newcomers attempt to use the above <command>svn update</command> example to <quote>undo</quote> committed changes, but this won't work as you can't commit changes that you obtain from backdating a working copy if the changed files have newer revisions. See <xref linkend=\"svn.branchmerge.commonuses.resurrect\"/> for a description of how to <quote>undo</quote> a commit."
3000 #: ../source/book.xml:3637
3001 msgid "Lastly, if you're building a release and wish to bundle up your files from Subversion but don't want those pesky <filename>.svn</filename> directories in the way, then you can use <command>svn export</command> to create a local copy of all or part of your repository sans <filename>.svn</filename> directories. As with <command>svn update</command> and <command>svn checkout</command>, you can also pass the <option>--revision</option> option to <command>svn export</command>:"
3005 #: ../source/book.xml:3647
3007 msgid "\n$ svn export http://svn.example.com/svn/repos1 # Exports latest revision\n…\n$ svn export http://svn.example.com/svn/repos1 -r 1729\n# Exports revision r1729\n…\n"
3011 #: ../source/book.xml:3661
3012 msgid "Sometimes You Just Need to Clean Up"
3016 #: ../source/book.xml:3663
3017 msgid "When Subversion modifies your working copy (or any information within <filename>.svn</filename>), it tries to do so as safely as possible. Before changing the working copy, Subversion writes its intentions to a log file. Next it executes the commands in the log file to apply the requested change, holding a lock on the relevant part of the working copy while it works—to prevent other Subversion clients from accessing the working copy in mid-change. Finally, Subversion removes the log file. Architecturally, this is similar to a journaled filesystem. If a Subversion operation is interrupted (if the process is killed, or if the machine crashes, for example), the log files remain on disk. By re-executing the log files, Subversion can complete the previously started operation, and your working copy can get itself back into a consistent state."
3021 #: ../source/book.xml:3678
3022 msgid "And this is exactly what <command>svn cleanup</command> does: it searches your working copy and runs any leftover logs, removing working copy locks in the process. If Subversion ever tells you that some part of your working copy is <quote>locked</quote>, then this is the command that you should run. Also, <command>svn status</command> will display an <literal>L</literal> next to locked items:"
3026 #: ../source/book.xml:3685
3028 msgid "\n$ svn status\n L somedir\nM somedir/foo.c\n\n$ svn cleanup\n$ svn status\nM somedir/foo.c\n"
3032 #: ../source/book.xml:3694
3033 msgid "Don't confuse these working copy locks with the ordinary locks that Subversion users create when using the <quote>lock-modify-unlock</quote> model of concurrent version control; see <xref linkend=\"svn.advanced.locking.meanings\"/> for clarification."
3037 #: ../source/book.xml:3708
3038 msgid "Now we've covered most of the Subversion client commands. Notable exceptions are those dealing with branching and merging (see <xref linkend=\"svn.branchmerge\"/>) and properties (see <xref linkend=\"svn.advanced.props\"/>). However, you may want to take a moment to skim through <xref linkend=\"svn.ref\"/> to get an idea of all the many different commands that Subversion has—and how you can use them to make your work easier."
3042 #: ../source/book.xml:3725
3043 msgid "Advanced Topics"
3047 #: ../source/book.xml:3727
3048 msgid "If you've been reading this book chapter by chapter, from start to finish, you should by now have acquired enough knowledge to use the Subversion client to perform the most common version control operations. You understand how to check out a working copy from a Subversion repository. You are comfortable with submitting and receiving changes using the <command>svn commit</command> and <command>svn update</command> functions. You've probably even developed a reflex which causes you to run the <command>svn status</command> command almost unconsciously. For all intents and purposes, you are ready to use Subversion in a typical environment."
3052 #: ../source/book.xml:3738
3053 msgid "But the Subversion feature set doesn't stop at <quote>common version control operations</quote>. It has other bits of functionality besides just communicating file and directory changes to and from a central repository."
3057 #: ../source/book.xml:3742
3058 msgid "This chapter highlights some of Subversion's features that, while important, aren't part of the typical user's daily routine. It assumes that you are familiar with Subversion's basic file and directory versioning capabilities. If you aren't, you'll want to first read <xref linkend=\"svn.basic\"/> and <xref linkend=\"svn.tour\"/>. Once you've mastered those basics and consumed this chapter, you'll be a Subversion power-user!"
3062 #: ../source/book.xml:3753
3063 msgid "Revision Specifiers"
3067 #: ../source/book.xml:3755
3068 msgid "As you saw in <xref linkend=\"svn.basic.in-action.revs\"/>, revision numbers in Subversion are pretty straightforward—integers that keep getting larger as you commit more changes to your versioned data. Still, it doesn't take long before you can no longer remember exactly what happened in each and every revision. Fortunately, the typical Subversion workflow doesn't often demand that you supply arbitrary revisions to the Subversion operations you perform. For operations that <emphasis>do</emphasis> require a revision specifier, you generally supply a revision number that you saw in a commit email, in the output of some other Subversion operation, or in some other context that would give meaning to that particular number."
3072 #: ../source/book.xml:3768
3073 msgid "But occasionally, you need to pinpoint a moment in time for which you don't already have a revision number memorized or handy. So besides the integer revision numbers, <command>svn</command> allows as input some additional forms of revision specifiers—<firstterm>revision keywords</firstterm>, and revision dates."
3077 #: ../source/book.xml:3775
3078 msgid "The various forms of Subversion revision specifiers can be mixed and matched when used to specify revision ranges. For example, you can use <option>-r <replaceable>REV1</replaceable>:<replaceable>REV2</replaceable></option> where <replaceable>REV1</replaceable> is a revision keyword and <replaceable>REV2</replaceable> is a revision number, or where <replaceable>REV1</replaceable> is a date and <replaceable>REV2</replaceable> is a revision keyword, and so on. The individual revision specifiers are independently evaluated, so you can put whatever you want on the opposite sides of that colon."
3082 #: ../source/book.xml:3790
3083 msgid "Revision Keywords"
3087 #: ../source/book.xml:3793 ../source/book.xml:3889
3092 #: ../source/book.xml:3794
3093 msgid "revision keywords"
3097 #: ../source/book.xml:3797 ../source/book.xml:3815
3102 #: ../source/book.xml:3800 ../source/book.xml:3822
3107 #: ../source/book.xml:3803 ../source/book.xml:3831
3112 #: ../source/book.xml:3806 ../source/book.xml:3838
3117 #: ../source/book.xml:3808
3118 msgid "The Subversion client understands a number of revision keywords. These keywords can be used instead of integer arguments to the <option>--revision (-r)</option> switch, and are resolved into specific revision numbers by Subversion:"
3122 #: ../source/book.xml:3817
3123 msgid "The latest (or <quote>youngest</quote>) revision in the repository."
3127 #: ../source/book.xml:3824
3128 msgid "The revision number of an item in a working copy. If the item has been locally modified, the <quote>BASE version</quote> refers to the way the item appears without those local modifications."
3132 #: ../source/book.xml:3833
3133 msgid "The most recent revision prior to, or equal to, <literal>BASE</literal>, in which an item changed."
3137 #: ../source/book.xml:3840
3138 msgid "The revision immediately <emphasis>before</emphasis> the last revision in which an item changed. Technically, this boils down to <literal>COMMITTED</literal>-1."
3142 #: ../source/book.xml:3847
3143 msgid "As can be derived from their descriptions, the <literal>PREV</literal>, <literal>BASE</literal>, and <literal>COMMITTED</literal> revision keywords are used only when referring to a working copy path—they don't apply to repository URLs. <literal>HEAD</literal>, on the other hand, can be used in conjunction with both of these path types."
3147 #: ../source/book.xml:3854
3148 msgid "Here are some examples of revision keywords in action:"
3152 #: ../source/book.xml:3856
3154 msgid "\n$ svn diff -r PREV:COMMITTED foo.c\n# shows the last change committed to foo.c\n\n$ svn log -r HEAD\n# shows log message for the latest repository commit\n\n$ svn diff -r HEAD\n# compares your working copy (with all of its local changes) to the\n# latest version of that tree in the repository\n\n$ svn diff -r BASE:HEAD foo.c\n# compares the unmodified version of foo.c with the latest version of\n# foo.c in the repository\n\n$ svn log -r BASE:HEAD\n# shows all commit logs for the current versioned directory since you\n# last updated\n\n$ svn update -r PREV foo.c\n# rewinds the last change on foo.c, decreasing foo.c's working revision\n\n$ svn diff -r BASE:14 foo.c\n# compares the unmodified version of foo.c with the way foo.c looked\n# in revision 14\n"
3158 #: ../source/book.xml:3886
3159 msgid "Revision Dates"
3163 #: ../source/book.xml:3890
3164 msgid "specified as dates"
3168 #: ../source/book.xml:3892
3169 msgid "Revision numbers reveal nothing about the world outside the version control system, but sometimes you need to correlate a moment in real time with a moment in version history. To facilitate this, the <option>--revision (-r)</option> option can also accept as input date specifiers wrapped in curly braces (<literal>{</literal> and <literal>}</literal>). Subversion accepts the standard ISO-8601 date and time formats, plus a few others. Here are some examples. (Remember to use quotes around any date that contains spaces.)"
3173 #: ../source/book.xml:3902
3175 msgid "\n$ svn checkout -r {2006-02-17}\n$ svn checkout -r {15:30}\n$ svn checkout -r {15:30:00.200000}\n$ svn checkout -r {\"2006-02-17 15:30\"}\n$ svn checkout -r {\"2006-02-17 15:30 +0230\"}\n$ svn checkout -r {2006-02-17T15:30}\n$ svn checkout -r {2006-02-17T15:30Z}\n$ svn checkout -r {2006-02-17T15:30-04:00}\n$ svn checkout -r {20060217T1530}\n$ svn checkout -r {20060217T1530Z}\n$ svn checkout -r {20060217T1530-0500}\n…\n"
3179 #: ../source/book.xml:3916
3180 msgid "When you specify a date, Subversion resolves that date to the most recent revision of the repository as of that date, and then continues to operate against that resolved revision number:"
3184 #: ../source/book.xml:3920
3186 msgid "\n$ svn log -r {2006-11-28}\n------------------------------------------------------------------------\nr12 | ira | 2006-11-27 12:31:51 -0600 (Mon, 27 Nov 2006) | 6 lines\n…\n"
3190 #: ../source/book.xml:3928
3191 msgid "Is Subversion a Day Early?"
3195 #: ../source/book.xml:3930
3196 msgid "If you specify a single date as a revision without specifying a time of day (for example <literal>2006-11-27</literal>), you may think that Subversion should give you the last revision that took place on the 27th of November. Instead, you'll get back a revision from the 26th, or even earlier. Remember that Subversion will find the <emphasis>most recent revision of the repository</emphasis> as of the date you give. If you give a date without a timestamp, like <literal>2006-11-27</literal>, Subversion assumes a time of 00:00:00, so looking for the most recent revision won't return anything on the day of the 27th."
3200 #: ../source/book.xml:3942
3201 msgid "If you want to include the 27th in your search, you can either specify the 27th with the time (<literal>{\"2006-11-27 23:59\"}</literal>), or just specify the next day (<literal>{2006-11-28}</literal>)."
3205 #: ../source/book.xml:3947
3206 msgid "You can also use a range of dates. Subversion will find all revisions between both dates, inclusive:"
3210 #: ../source/book.xml:3949
3212 msgid "\n$ svn log -r {2006-11-20}:{2006-11-29}\n…\n"
3216 #: ../source/book.xml:3954
3217 msgid "Since the timestamp of a revision is stored as an unversioned, modifiable property of the revision (see <xref linkend=\"svn.advanced.props\"/>, revision timestamps can be changed to represent complete falsifications of true chronology, or even removed altogether. Subversion's ability to correctly convert revision dates into real revision numbers depends on revision datestamps maintaining a sequential ordering—the younger the revision, the younger its timestamp. If this ordering isn't maintained, you will likely find that trying to use dates to specify revision ranges in your repository doesn't always return the data you might have expected."
3221 #: ../source/book.xml:3973
3226 #: ../source/book.xml:3976
3231 #: ../source/book.xml:3978
3232 msgid "We've already covered in detail how Subversion stores and retrieves various versions of files and directories in its repository. Whole chapters have been devoted to this most fundamental piece of functionality provided by the tool. And if the versioning support stopped there, Subversion would still be complete from a version control perspective."
3236 #: ../source/book.xml:3984
3237 msgid "But it doesn't stop there."
3241 #: ../source/book.xml:3985
3242 msgid "In addition to versioning your directories and files, Subversion provides interfaces for adding, modifying, and removing versioned metadata on each of your versioned directories and files. We refer to this metadata as <firstterm>properties</firstterm>, and they can be thought of as two-column tables that map property names to arbitrary values attached to each item in your working copy. Generally speaking, the names and values of the properties can be whatever you want them to be, with the constraint that the names must be human-readable text. And the best part about these properties is that they, too, are versioned, just like the textual contents of your files. You can modify, commit, and revert property changes as easily as you can file content changes. And the sending and receiving of property changes occurs as part of your typical commit and update operations—you don't have to change your basic processes to accommodate them."
3246 #: ../source/book.xml:4002
3247 msgid "Subversion has reserved the set of properties whose names begin with <literal>svn:</literal> as its own. While there are only a handful of such properties in use today, you should avoid creating custom properties for your own needs whose names begin with this prefix. Otherwise, you run the risk that a future release of Subversion will grow support for a feature or behavior driven by a property of the same name but with perhaps an entirely different interpretation."
3251 #: ../source/book.xml:4011
3252 msgid "Properties show up elsewhere in Subversion, too. Just as files and directories may have arbitrary property names and values attached to them, each revision as a whole may have arbitrary properties attached to it. The same constraints apply—human-readable names and anything-you-want binary values. The main difference is that revision properties are not versioned. In other words, if you change the value of, or delete, a revision property, there's no way within the scope of Subversion's functionality to recover the previous value."
3256 #: ../source/book.xml:4020
3257 msgid "Subversion has no particular policy regarding the use of properties. It asks only that you not use property names that begin with the prefix <literal>svn:</literal>. That's the namespace that it sets aside for its own use. And Subversion does, in fact, use properties, both the versioned and unversioned variety. Certain versioned properties have special meaning or effects when found on files and directories, or house a particular bit of information about the revisions on which they are found. Certain revision properties are automatically attached to revisions by Subversion's commit process, and carry information about the revision. Most of these properties are mentioned elsewhere in this or other chapters as part of the more general topics to which they are related. For an exhaustive list of Subversion's pre-defined properties, see <xref linkend=\"svn.ref.properties\"/>."
3261 #: ../source/book.xml:4035
3262 msgid "In this section, we will examine the utility—both to users of Subversion, and to Subversion itself—of property support. You'll learn about the property-related <command>svn</command> subcommands, and how property modifications affect your normal Subversion workflow."
3266 #: ../source/book.xml:4043
3267 msgid "Why Properties?"
3271 #: ../source/book.xml:4045
3272 msgid "Just as Subversion uses properties to store extra information about the files, directories, and revisions that it contains, you might also find properties to be of similar use. You might find it useful to have a place close to your versioned data to hang custom metadata about that data."
3276 #: ../source/book.xml:4051
3277 msgid "Say you wish to design a website that houses many digital photos, and displays them with captions and a datestamp. Now, your set of photos is constantly changing, so you'd like to have as much of this site automated as possible. These photos can be quite large, so as is common with sites of this nature, you want to provide smaller thumbnail images to your site visitors."
3281 #: ../source/book.xml:4058
3282 msgid "Now, you can get this functionality using traditional files. That is, you can have your <filename>image123.jpg</filename> and an <filename>image123-thumbnail.jpg</filename> side-by-side in a directory. Or if you want to keep the filenames the same, you might have your thumbnails in a different directory, like <filename>thumbnails/image123.jpg</filename>. You can also store your captions and datestamps in a similar fashion, again separated from the original image file. But the problem here is that your collection of files grows in multiples with each new photo added to the site."
3286 #: ../source/book.xml:4069
3287 msgid "Now consider the same website deployed in a way that makes use of Subversion's file properties. Imagine having a single image file, <filename>image123.jpg</filename>, and then properties set on that file named <literal>caption</literal>, <literal>datestamp</literal>, and even <literal>thumbnail</literal>. Now your working copy directory looks much more manageable—in fact, it looks to the casual browser like there are nothing but image files in it. But your automation scripts know better. They know that they can use <command>svn</command> (or better yet, they can use the Subversion language bindings—see <xref linkend=\"svn.developer.usingapi\"/>) to dig out the extra information that your site needs to display without having to read an index file or play path manipulation games."
3291 #: ../source/book.xml:4083
3292 msgid "Custom revision properties are also frequently used. One common such use is a property whose value contains an issue tracker ID with which the revision is associated, perhaps because the change made in that revision fixes a bug filed in the tracker issue with that ID. Other uses include hanging more friendly names on the revision—it might be hard to remember that revision 1935 was a fully tested revision. But if there's, say, a <literal>test-results</literal> property on that revision with a value <literal>all passing</literal>, that's meaningful information to have."
3296 #: ../source/book.xml:4095
3297 msgid "Searchability (or, Why <emphasis>Not</emphasis> Properties)"
3301 #: ../source/book.xml:4098
3302 msgid "For all their utility, Subversion properties—or, more accurately, the available interfaces to them—have a major shortcoming: while it is a simple matter to <emphasis>set</emphasis> a custom property, <emphasis>finding</emphasis> that property later is whole different ball of wax."
3306 #: ../source/book.xml:4104
3307 msgid "Trying to locate a custom revision property generally involves performing a linear walk across all the revisions of the repository, asking of each revision, \"Do you have the property I'm looking for?\" Trying to find a custom versioned property is painful, too, and often involves a recursive <command>svn propget</command> across an entire working copy. In your situation, that might not be as bad as a linear walk across all revisions. But it certainly leaves much to be desired in terms of both performance and likelihood of success, especially if the scope of your search would require a working copy from the root of your repository."
3311 #: ../source/book.xml:4116
3312 msgid "For this reason, you might choose—especially in the revision property use-case—to simply add your metadata to the revision's log message, using some policy-driven (and perhaps programmatically-enforced) formatting that is designed to be quickly parsed from the output of <command>svn log</command>. It is quite common to see in Subversion log messages the likes of:"
3316 #: ../source/book.xml:4123
3318 msgid "\nIssue(s): IZ2376, IZ1919\nReviewed by: sally\n\nThis fixes a nasty segfault in the wort frabbing process\n…\n"
3322 #: ../source/book.xml:4130
3323 msgid "But here again lies some misfortune. Subversion doesn't yet provide a log message templating mechanism, which would go a long way toward helping users be consistent with the formatting of their log-embedded revision metadata."
3327 #: ../source/book.xml:4139
3328 msgid "Manipulating Properties"
3332 #: ../source/book.xml:4141
3333 msgid "The <command>svn</command> command affords a few ways to add or modify file and directory properties. For properties with short, human-readable values, perhaps the simplest way to add a new property is to specify the property name and value on the command line of the <command>propset</command> subcommand."
3337 #: ../source/book.xml:4147
3339 msgid "\n$ svn propset copyright '(c) 2006 Red-Bean Software' calc/button.c\nproperty 'copyright' set on 'calc/button.c'\n$\n"
3343 #: ../source/book.xml:4152
3344 msgid "But we've been touting the flexibility that Subversion offers for your property values. And if you are planning to have a multi-line textual, or even binary, property value, you probably do not want to supply that value on the command line. So the <command>propset</command> subcommand takes a <option>--file (-F)</option> option for specifying the name of a file which contains the new property value."
3348 #: ../source/book.xml:4159
3350 msgid "\n$ svn propset license -F /path/to/LICENSE calc/button.c\nproperty 'license' set on 'calc/button.c'\n$\n"
3354 #: ../source/book.xml:4170
3355 msgid "If you're familiar with XML, this is pretty much the ASCII subset of the syntax for XML \"Name\"."
3359 #: ../source/book.xml:4164
3360 msgid "There are some restrictions on the names you can use for properties. A property name must start with a letter, a colon (<literal>:</literal>), or an underscore (<literal>_</literal>); after that, you can also use digits, hyphens (<literal>-</literal>), and periods (<literal>.</literal>). <placeholder-1/>"
3364 #: ../source/book.xml:4173
3365 msgid "In addition to the <command>propset</command> command, the <command>svn</command> program supplies the <command>propedit</command> command. This command uses the configured editor program (see <xref linkend=\"svn.advanced.confarea.opts.config\"/>) to add or modify properties. When you run the command, <command>svn</command> invokes your editor program on a temporary file that contains the current value of the property (or which is empty, if you are adding a new property). Then, you just modify that value in your editor program until it represents the new value you wish to store for the property, save the temporary file, and then exit the editor program. If Subversion detects that you've actually changed the existing value of the property, it will accept that as the new property value. If you exit your editor without making any changes, no property modification will occur:"
3369 #: ../source/book.xml:4188
3371 msgid "\n$ svn propedit copyright calc/button.c ### exit the editor without changes\nNo changes to property 'copyright' on 'calc/button.c'\n$\n"
3375 #: ../source/book.xml:4193
3376 msgid "We should note that, as with other <command>svn</command> subcommands, those related to properties can act on multiple paths at once. This enables you to modify properties on whole sets of files with a single command. For example, we could have done:"
3380 #: ../source/book.xml:4198
3382 msgid "\n$ svn propset copyright '(c) 2006 Red-Bean Software' calc/*\nproperty 'copyright' set on 'calc/Makefile'\nproperty 'copyright' set on 'calc/button.c'\nproperty 'copyright' set on 'calc/integer.c'\n…\n$\n"
3386 #: ../source/book.xml:4206
3387 msgid "All of this property adding and editing isn't really very useful if you can't easily get the stored property value. So the <command>svn</command> program supplies two subcommands for displaying the names and values of properties stored on files and directories. The <command>svn proplist</command> command will list the names of properties that exist on a path. Once you know the names of the properties on the node, you can request their values individually using <command>svn propget</command>. This command will, given a property name and a path (or set of paths), print the value of the property to the standard output stream."
3391 #: ../source/book.xml:4217
3393 msgid "\n$ svn proplist calc/button.c\nProperties on 'calc/button.c':\n copyright\n license\n$ svn propget copyright calc/button.c\n(c) 2006 Red-Bean Software\n"
3397 #: ../source/book.xml:4225
3398 msgid "There's even a variation of the <command>proplist</command> command that will list both the name and value of all of the properties. Simply supply the <option>--verbose</option> (<option>-v</option>) option."
3402 #: ../source/book.xml:4229
3404 msgid "\n$ svn proplist -v calc/button.c\nProperties on 'calc/button.c':\n copyright : (c) 2006 Red-Bean Software\n license : ================================================================\nCopyright (c) 2006 Red-Bean Software. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions \nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions, and the recipe for Fitz's famous\nred-beans-and-rice.\n…\n"
3408 #: ../source/book.xml:4245
3409 msgid "The last property-related subcommand is <command>propdel</command>. Since Subversion allows you to store properties with empty values, you can't remove a property altogether using <command>propedit</command> or <command>propset</command>. For example, this command will <emphasis>not</emphasis> yield the desired effect:"
3413 #: ../source/book.xml:4251
3415 msgid "\n$ svn propset license '' calc/button.c\nproperty 'license' set on 'calc/button.c'\n$ svn proplist -v calc/button.c\nProperties on 'calc/button.c':\n copyright : (c) 2006 Red-Bean Software\n license : \n$\n"
3419 #: ../source/book.xml:4260
3420 msgid "You need to use the <command>propdel</command> subcommand to delete properties altogether. The syntax is similar to the other property commands:"
3424 #: ../source/book.xml:4263
3426 msgid "\n$ svn propdel license calc/button.c\nproperty 'license' deleted from 'calc/button.c'.\n$ svn proplist -v calc/button.c\nProperties on 'calc/button.c':\n copyright : (c) 2006 Red-Bean Software\n$\n"
3430 #: ../source/book.xml:4284
3431 msgid "Fixing spelling errors, grammatical gotchas, and <quote>just-plain-wrongness</quote> in commit log messages is perhaps the most common use case for the <option>--revprop</option> option."
3435 #: ../source/book.xml:4271
3436 msgid "Remember those unversioned revision properties? You can modify those, too, using the same <command>svn</command> subcommands that we just described. Simply add the <option>--revprop</option> command-line parameter, and specify the revision whose property you wish to modify. Since revisions are global, you don't need to specify a target path to these property-related commands so long as you are positioned in a working copy of the repository whose revision property you wish to modify. Otherwise, you can simply provide the URL of any path in the repository of interest (including the repository's root URL). For example, you might want to replace the commit log message of an existing revision. <placeholder-1/> If your current working directory is part of a working copy of your repository, you can simply run the <command>svn propset</command> command with no target path:"
3440 #: ../source/book.xml:4291
3442 msgid "\n$ svn propset svn:log '* button.c: Fix a compiler warning.' -r11 --revprop\nproperty 'svn:log' set on repository revision '11'\n$\n"
3446 #: ../source/book.xml:4296
3447 msgid "But even if you haven't checked out a working copy from that repository, you can still affect the property change by providing the repository's root URL:"
3451 #: ../source/book.xml:4299
3453 msgid "\n$ svn propset svn:log '* button.c: Fix a compiler warning.' -r11 --revprop \\\n http://svn.example.com/repos/project\nproperty 'svn:log' set on repository revision '11'\n$\n"
3457 #: ../source/book.xml:4305
3458 msgid "Note that the ability to modify these unversioned properties must be explicitly added by the repository administrator (see <xref linkend=\"svn.reposadmin.maint.setlog\"/>). That's because the properties aren't versioned, so you run the risk of losing information if you aren't careful with your edits. The repository administrator can set up methods to protect against this loss, and by default, modification of unversioned properties is disabled."
3462 #: ../source/book.xml:4314
3463 msgid "Users should, where possible, use <command>svn propedit</command> instead of <command>svn propset</command>. While the end result of the commands is identical, the former will allow them to see the current value of the property they are about to change, which helps them to verify that they are, in fact, making the change they think they are making. This is especially true when modifying unversioned revision properties. Also, it is significantly easier to modify multiline property values in a text editor than at the command line."
3467 #: ../source/book.xml:4329
3468 msgid "Properties and the Subversion Workflow"
3472 #: ../source/book.xml:4331
3473 msgid "Now that you are familiar with all of the property-related <command>svn</command> subcommands, let's see how property modifications affect the usual Subversion workflow. As we mentioned earlier, file and directory properties are versioned, just like your file contents. As a result, Subversion provides the same opportunities for merging—cleanly or with conflicts—someone else's modifications into your own."
3477 #: ../source/book.xml:4339
3478 msgid "And as with file contents, your property changes are local modifications, only made permanent when you commit them to the repository with <command>svn commit</command>. Your property changes can be easily unmade, too—the <command>svn revert</command> command will restore your files and directories to their un-edited states—contents, properties, and all. Also, you can receive interesting information about the state of your file and directory properties by using the <command>svn status</command> and <command>svn diff</command> commands."
3482 #: ../source/book.xml:4349
3484 msgid "\n$ svn status calc/button.c\n M calc/button.c\n$ svn diff calc/button.c\nProperty changes on: calc/button.c\n___________________________________________________________________\nName: copyright\n + (c) 2006 Red-Bean Software\n\n$\n"
3488 #: ../source/book.xml:4360
3489 msgid "Notice how the <command>status</command> subcommand displays <literal>M</literal> in the second column instead of the first. That is because we have modified the properties on <filename>calc/button.c</filename>, but not its textual contents. Had we changed both, we would have seen <literal>M</literal> in the first column, too (see <xref linkend=\"svn.tour.cycle.examine.status\"/>)."
3493 #: ../source/book.xml:4368
3494 msgid "Property Conflicts"
3498 #: ../source/book.xml:4370
3499 msgid "As with file contents, local property modifications can conflict with changes committed by someone else. If you update your working copy directory and receive property changes on a versioned object that clash with your own, Subversion will report that the object is in a conflicted state."
3503 #: ../source/book.xml:4376
3505 msgid "\n% svn update calc\nM calc/Makefile.in\n C calc/button.c\nUpdated to revision 143.\n$ \n"
3509 #: ../source/book.xml:4383
3510 msgid "Subversion will also create, in the same directory as the conflicted object, a file with a <filename>.prej</filename> extension which contains the details of the conflict. You should examine the contents of this file so you can decide how to resolve the conflict. Until the conflict is resolved, you will see a <literal>C</literal> in the second column of <command>svn status</command> output for that object, and attempts to commit your local modifications will fail."
3514 #: ../source/book.xml:4392
3516 msgid "\n$ svn status calc\n C calc/button.c\n? calc/button.c.prej\n$ cat calc/button.c.prej \nprop 'linecount': user set to '1256', but update set to '1301'.\n$\n"
3520 #: ../source/book.xml:4400
3521 msgid "To resolve property conflicts, simply ensure that the conflicting properties contain the values that they should, and then use the <command>svn resolved</command> command to alert Subversion that you have manually resolved the problem."
3525 #: ../source/book.xml:4406
3526 msgid "You might also have noticed the non-standard way that Subversion currently displays property differences. You can still run <command>svn diff</command> and redirect the output to create a usable patch file. The <command>patch</command> program will ignore property patches—as a rule, it ignores any noise it can't understand. This does, unfortunately, mean that to fully apply a patch generated by <command>svn diff</command>, any property modifications will need to be applied by hand."
3530 #: ../source/book.xml:4419
3531 msgid "Automatic Property Setting"
3535 #: ../source/book.xml:4421
3536 msgid "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 step can be easily forgotten in the routine of things, especially since failing to set a property doesn't usually result in an obvious error (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."
3540 #: ../source/book.xml:4433
3541 msgid "Whenever you introduce a file to version control using the <command>svn add</command> or <command>svn import</command> commands, Subversion tries to assist by setting some common file properties automatically. First, on operating systems whose filesystems support an execute permission bit, Subversion will automatically set the <literal>svn:executable</literal> property on newly added or imported files whose execute bit is enabled. (See <xref linkend=\"svn.advanced.props.special.executable\"/> for more about this property.) Secondly, it runs a very basic heuristic to determine if that file contains human-readable content. If not, Subversion will automatically set the <literal>svn:mime-type</literal> property on that file to <literal>application/octet-stream</literal> (the generic <quote>this is a collection of bytes</quote> MIME type). Of course, if Subversion guesses incorrectly, or if you wish to set the <literal>svn:mime-type</literal> property to something more precise—perhaps <literal>image/png</literal> or <literal>application/x-shockwave-flash</literal>—you can always remove or edit that property. (For more on Subversion's use of MIME types, see <xref linkend=\"svn.advanced.props.special.mime-type\"/>.)"
3545 #: ../source/book.xml:4453
3546 msgid "Subversion also provides, via its runtime configuration system (see <xref linkend=\"svn.advanced.confarea\"/>), a more flexible automatic property setting feature which allows you to create mappings of filename patterns to property names and values. Once again, these mappings affect adds and imports, and can not only override the default MIME type decision made by Subversion during those operations, but 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 whose names match the pattern <literal>*.jpg</literal>—Subversion should automatically set the <literal>svn:mime-type</literal> property on those files to <literal>image/jpeg</literal>. Or perhaps any files that match <literal>*.cpp</literal> should have <literal>svn:eol-style</literal> set to <literal>native</literal>, and <literal>svn:keywords</literal> set to <literal>Id</literal>. Automatic property support is perhaps the handiest property-related tool in the Subversion toolbox. See <xref linkend=\"svn.advanced.confarea.opts.config\"/> for more about configuring that support."
3550 #: ../source/book.xml:4480
3551 msgid "File Portability"
3555 #: ../source/book.xml:4482
3556 msgid "Fortunately for Subversion users who routinely find themselves on different computers with different operating systems, Subversion's command-line program behaves almost identically on all those systems. If you know how to wield <command>svn</command> on one platform, you know how to wield it everywhere."
3560 #: ../source/book.xml:4488
3561 msgid "However, the same is not always true of other general classes of software, or of the actual files you keep in Subversion. For example, on a Windows machine, the definition of a <quote>text file</quote> would be similar to that used on a Linux box, but with a key difference—the character sequences used to mark the ends of the lines of those files. There are other differences, too. Unix platforms have (and Subversion supports) symbolic links; Windows does not. Unix platforms use filesystem permission to determine executability; Windows uses filename extensions."
3565 #: ../source/book.xml:4498
3566 msgid "Because Subversion is in no position to unite the whole world in common definitions and implementations of all of these things, the best it can do is to try to help make your life simpler when you need to work with your versioned files and directories on multiple computers and operating systems. This section describes some of the ways Subversion does this."
3570 #: ../source/book.xml:4507
3571 msgid "File Content Type"
3575 #: ../source/book.xml:4509
3576 msgid "Subversion joins the ranks of the many applications which recognize and make use of Multipurpose Internet Mail Extensions (MIME) content types. Besides being a general-purpose storage location for a file's content type, the value of the <literal>svn:mime-type</literal> file property determines some behavioral characteristics of Subversion itself."
3580 #: ../source/book.xml:4518
3581 msgid "Identifying File Types"
3585 #: ../source/book.xml:4520
3586 msgid "Various programs on most modern operating systems make assumptions about the type and format of the contents of a file by the file's name, specifically its file extension. For example, files whose names end in <filename>.txt</filename> are generally assumed to be human-readable, able to be understood by simple perusal rather than requiring complex processing to decipher. Files whose names end in <filename>.png</filename>, on the other hand, are assumed to be of the Portable Network Graphics type—not human-readable at all, and sensible only when interpreted by software which understands the PNG format and can render the information in that format as a raster image."
3590 #: ../source/book.xml:4545
3591 msgid "You think that was rough? During that same era, WordPerfect also used <filename>.DOC</filename> for their proprietary file format's preferred extension!"
3595 #: ../source/book.xml:4533
3596 msgid "Unfortunately, some of those extensions have changed their meanings over time. When personal computers first appeared, a file named <filename>README.DOC</filename> would have almost certainly been a plaintext file, just like today's <filename>.txt</filename> files. But by the mid-1990's, you could almost bet that a file of that name would not be a plaintext file at all, but instead a Microsoft Word document in a proprietary, non-human-readable format. But this change didn't occur overnight—there was certainly a period of confusion for computer users over what exactly they had in hand when they saw a <filename>.DOC</filename> file. <placeholder-1/>"
3600 #: ../source/book.xml:4549
3601 msgid "The popularity of computer networking cast still more doubt on the mapping between a file's name and its content. With information being served across networks and generated dynamically by server-side scripts, there was often no real file per se, and therefore no file name. Web servers, for example, needed some other way to tell browsers what they were downloading so the browser could do something intelligent with that information, whether that was to display the data using a program registered to handle that data type, or to prompt the user for where on the client machine to store the downloaded data."
3605 #: ../source/book.xml:4560
3606 msgid "Eventually, a standard emerged for, among other things, describing the contents of a data stream. In 1996, RFC2045 was published, the first of five RFCs describing MIME. It describes the concept of media types and subtypes, and recommends a syntax for the representation of those types. Today, MIME media types—or <quote>MIME types</quote>—are used almost universally across e-mail applications, Web servers, and other software as the de facto mechanism for clearing up the file content confusion."
3610 #: ../source/book.xml:4571
3611 msgid "For example, one of the benefits that Subversion typically provides is contextual, line-based merging of changes received from the server during an update into your working file. But for files containing non-textual data, there is often no concept of a <quote>line</quote>. So, for versioned files whose <literal>svn:mime-type</literal> property is set to a non-textual MIME type (generally, something that doesn't begin with <literal>text/</literal>, though there are exceptions), Subversion does not attempt to perform contextual merges during updates. Instead, any time you have locally modified a binary working copy file that is also being updated, your file is left untouched and Subversion creates two new files. One file has a <filename>.oldrev</filename> extension and contains the BASE revision of the file. The other file has a <filename>.newrev</filename> extension and contains the contents of the updated revision of the file. This behavior is really for the protection of the user against failed attempts at performing contextual merges on files that simply cannot be contextually merged."
3615 #: ../source/book.xml:4590
3616 msgid "Also, if the <literal>svn:mime-type</literal> property is set, then the Subversion Apache module will use its value to populate the <literal>Content-type:</literal> HTTP header when responding to GET requests. This gives your web browser a crucial clue about how to display a file when you use it to peruse your Subversion repository's contents."
3620 #: ../source/book.xml:4600
3621 msgid "File Executability"
3625 #: ../source/book.xml:4602
3626 msgid "On many operating systems, the ability to execute a file as a command is governed by the presence of an execute permission bit. This bit usually defaults to being disabled, and must be explicitly enabled by the user for each file that needs it. But it would be a monumental hassle to have to remember exactly which files in freshly checked-out working copy were supposed to have their executable bits toggled on, and then to have to do that toggling. So, Subversion provides the <literal>svn:executable</literal> property as a way to specify that the executable bit for the file on which that property is set should be enabled, and Subversion honors that request when populating working copies with such files."
3630 #: ../source/book.xml:4617
3631 msgid "The Windows filesystems use file extensions (such as <literal>.EXE</literal>, <literal>.BAT</literal>, and <literal>.COM</literal>) to denote executable files."
3635 #: ../source/book.xml:4614
3636 msgid "This property has no effect on filesystems that have no concept of an executable permission bit, such as FAT32 and NTFS. <placeholder-1/> Also, although it has no defined values, Subversion will force its value to <literal>*</literal> when setting this property. Finally, this property is valid only on files, not on directories."
3640 #: ../source/book.xml:4629
3641 msgid "End-of-Line Character Sequences"
3645 #: ../source/book.xml:4631
3646 msgid "Unless otherwise noted using a versioned file's <literal>svn:mime-type</literal> property, Subversion assumes the file contains human-readable data. Generally speaking, Subversion only uses this knowledge to determine if contextual difference reports for that file are possible. Otherwise, to Subversion, bytes are bytes."
3650 #: ../source/book.xml:4637
3651 msgid "This means that by default, Subversion doesn't pay any attention to the type of <firstterm>end-of-line (EOL) markers</firstterm> used in your files. Unfortunately, different operating systems have different conventions about which character sequences represent the end of a line of text in a file. For example, the usual line ending token used by software on the Windows platform is a pair of ASCII control characters—a carriage return (<literal>CR</literal>) followed by a line feed (<literal>LF</literal>). Unix software, however, just uses the <literal>LF</literal> character to denote the end of a line."
3655 #: ../source/book.xml:4648
3656 msgid "Not all of the various tools on these operating systems understand files that contain line endings in a format that differs from the <firstterm>native line ending style</firstterm> of the operating system on which they are running. So, typically, Unix programs treat the <literal>CR</literal> character present in Windows files as a regular character (usually rendered as <literal>^M</literal>), and Windows programs combine all of the lines of a Unix file into one giant line because no carriage return-linefeed (or <literal>CRLF</literal>) character combination was found to denote the ends of the lines."
3660 #: ../source/book.xml:4660
3661 msgid "This sensitivity to foreign EOL markers can be frustrating for folks who share a file across different operating systems. For example, consider a source code file, and developers that edit this file on both Windows and Unix systems. If all the developers always use tools which preserve the line ending style of the file, no problems occur."
3665 #: ../source/book.xml:4667
3666 msgid "But in practice, many common tools either fail to properly read a file with foreign EOL markers, or they convert the file's line endings to the native style when the file is saved. If the former is true for a developer, he has to use an external conversion utility (such as <command>dos2unix</command> or its companion, <command>unix2dos</command>) to prepare the file for editing. The latter case requires no extra preparation. But both cases result in a file that differs from the original quite literally on every line! Prior to committing his changes, the user has two choices. Either he can use a conversion utility to restore the modified file to the same line ending style that it was in before his edits were made. Or, he can simply commit the file—new EOL markers and all."
3670 #: ../source/book.xml:4682
3671 msgid "The result of scenarios like these include wasted time and unnecessary modifications to committed files. Wasted time is painful enough. But when commits change every line in a file, this complicates the job of determining which of those lines were changed in a non-trivial way. Where was that bug really fixed? On what line was a syntax error introduced?"
3675 #: ../source/book.xml:4689
3676 msgid "The solution to this problem is the <literal>svn:eol-style</literal> property. When this property is set to a valid value, Subversion uses it to determine what special processing to perform on the file so that the file's line ending style isn't flip-flopping with every commit that comes from a different operating system. The valid values are:"
3680 #: ../source/book.xml:4699
3685 #: ../source/book.xml:4702
3686 msgid "This causes the file to contain the EOL markers that are native to the operating system on which Subversion was run. In other words, if a user on a Windows machine checks out a working copy that contains a file with an <literal>svn:eol-style</literal> property set to <literal>native</literal>, that file will contain <literal>CRLF</literal> EOL markers. A Unix user checking out a working copy which contains the same file will see <literal>LF</literal> EOL markers in his copy of the file."
3690 #: ../source/book.xml:4713
3691 msgid "Note that Subversion will actually store the file in the repository using normalized <literal>LF</literal> EOL markers regardless of the operating system. This is basically transparent to the user, though."
3695 #: ../source/book.xml:4722
3700 #: ../source/book.xml:4725
3701 msgid "This causes the file to contain <literal>CRLF</literal> sequences for EOL markers, regardless of the operating system in use."
3705 #: ../source/book.xml:4732
3710 #: ../source/book.xml:4735
3711 msgid "This causes the file to contain <literal>LF</literal> characters for EOL markers, regardless of the operating system in use."
3715 #: ../source/book.xml:4742
3720 #: ../source/book.xml:4745
3721 msgid "This causes the file to contain <literal>CR</literal> characters for EOL markers, regardless of the operating system in use. This line ending style is not very common. It was used on older Macintosh platforms (on which Subversion doesn't even run)."
3725 #: ../source/book.xml:4761
3726 msgid "Ignoring Unversioned Items"
3730 #: ../source/book.xml:4763
3731 msgid "In any given working copy there is a good chance that alongside all those versioned files and directories are other files and directories which are neither versioned nor intended to be. Text editors litter directories with backup files. Software compilers generate intermediate—or even final—files which you typically wouldn't bother to version. And users themselves drop various other files and directories wherever they see fit, often in version control working copies."
3735 #: ../source/book.xml:4772
3736 msgid "It's ludicrous to expect Subversion working copies to be somehow impervious to this kind of clutter and impurity. In fact, Subversion counts it as a <emphasis>feature</emphasis> that its working copies are just typical directories, just like unversioned trees. But these not-to-be-versioned files and directories can cause some annoyance for Subversion users. For example, because the <command>svn add</command> and <command>svn import</command> commands act recursively by default, and don't know which files in a given tree you do and don't wish to version, it's easy to accidentally add stuff to version control that you didn't mean to. And because <command>svn status</command> reports, by default, every item of interest in a working copy—including unversioned files and directories—its output can get quite noisy where many of these things exist."
3740 #: ../source/book.xml:4787
3741 msgid "So Subversion provides two ways for telling it which files you would prefer that it simply disregard. One of the ways involves the use of Subversion's runtime configuration system (see <xref linkend=\"svn.advanced.confarea\"/>), and therefore applies to all the Subversion operations which make use of that runtime configuration, generally those performed on a particular computer, or by a particular user of a computer. The other way makes use of Subversion's directory property support, is more tightly bound to the versioned tree itself, and therefore affects everyone who has a working copy of that tree. Both of the mechanisms use file patterns."
3745 #: ../source/book.xml:4798
3746 msgid "The Subversion runtime configuration system provides an option, <literal>global-ignores</literal>, whose value is a whitespace-delimited collection of file patterns (also known as <firstterm>globs</firstterm>). The Subversion client checks these patterns against the names of the files which are candidates for addition to version control, as well as to unversioned files which the <command>svn status</command> command notices. If any file's name matches one of the patterns, Subversion will basically act as if the file didn't exist at all. This is really useful for the kinds of files that you almost never want to version, such as editor backup files like Emacs' <literal>*~</literal> and <literal>.*~</literal> files."
3750 #: ../source/book.xml:4811
3751 msgid "When found on a versioned directory, the <literal>svn:ignore</literal> property is expected to contain a list of newline-delimited file patterns which Subversion should use to determine ignorable objects in that same directory. These patterns do not override those found in the <literal>global-ignores</literal> runtime configuration option, but are instead appended to that list. And it's worth noting again that, unlike the <literal>global-ignores</literal> option, the patterns found in the <literal>svn:ignore</literal> property apply only to the directory on which that property is set, and not to any of its subdirectories. The <literal>svn:ignore</literal> property is a good way to tell Subversion to ignore files that are likely to be present in every user's working copy of that directory, such as compiler output or—to use an example more appropriate to this book—the HTML, PDF, or PostScript files generated as the result of a conversion of some source DocBook XML files to a more legible output format."
3755 #: ../source/book.xml:4830
3756 msgid "Subversion's support for ignorable file patterns extends only to the one-time process of adding unversioned files and directories to version control. Once an object is under Subversion's control, the ignore pattern mechanisms no longer apply to it. In other words, don't expect Subversion to avoid committing changes you've made to a versioned file simply because that file's name matches an ignore pattern—Subversion <emphasis>always</emphasis> notices all of its versioned objects."
3760 #: ../source/book.xml:4842
3761 msgid "Ignore Patterns for CVS Users"
3765 #: ../source/book.xml:4844
3766 msgid "The Subversion <literal>svn:ignore</literal> property is very similar in syntax and function to the CVS <filename>.cvsignore</filename> file. In fact, if you are migrating a CVS working copy to Subversion, you can directly migrate the ignore patterns by using the <filename>.cvsignore</filename> file as input file to the <command>svn propset</command> command:"
3770 #: ../source/book.xml:4851
3772 msgid "\n$ svn propset svn:ignore -F .cvsignore .\nproperty 'svn:ignore' set on '.'\n$\n"
3776 #: ../source/book.xml:4856
3777 msgid "There are, however, some differences in the ways that CVS and Subversion handle ignore patterns. The two systems use the ignore patterns at some different times, and there are slight discrepancies in what the ignore patterns apply to. Also, Subversion does not recognize the use of the <literal>!</literal> pattern as a reset back to having no ignore patterns at all."
3781 #: ../source/book.xml:4864
3782 msgid "The global list of ignore patterns tends to be more a matter of personal taste, and tied more closely to a user's particular tool chain than to the details of any particular working copy's needs. So, the rest of this section will focus on the <literal>svn:ignore</literal> property and its uses."
3786 #: ../source/book.xml:4870
3787 msgid "Say you have the following output from <command>svn status</command>:"
3791 #: ../source/book.xml:4872
3793 msgid "\n$ svn status calc\n M calc/button.c\n? calc/calculator\n? calc/data.c\n? calc/debug_log\n? calc/debug_log.1\n? calc/debug_log.2.gz\n? calc/debug_log.3.gz\n"
3797 #: ../source/book.xml:4890
3798 msgid "Isn't that the whole point of a build system?"
3802 #: ../source/book.xml:4882
3803 msgid "In this example, you have made some property modifications to <filename>button.c</filename>, but in your working copy you also have some unversioned files: the latest <filename>calculator</filename> program that you've compiled from your source code, a source file named <filename>data.c</filename>, and a set of debugging output log files. Now, you know that your build system always results in the <filename>calculator</filename> program being generated. <placeholder-1/> And you know that your test suite always leaves those debugging log files lying around. These facts are true for all working copies of this project, not just your own. And you know that you aren't interested in seeing those things every time you run <command>svn status</command>, and pretty sure that nobody else is interested in them either. So you use <command>svn propedit svn:ignore calc</command> to add some ignore patterns to the <filename>calc</filename> directory. For example, you might add this as the new value of the <literal>svn:ignore</literal> property:"
3807 #: ../source/book.xml:4901
3809 msgid "\ncalculator\ndebug_log*\n"
3813 #: ../source/book.xml:4905
3814 msgid "After you've added this property, you will now have a local property modification on the <filename>calc</filename> directory. But notice what else is different about your <command>svn status</command> output:"
3818 #: ../source/book.xml:4909
3820 msgid "\n$ svn status\n M calc\n M calc/button.c\n? calc/data.c\n"
3824 #: ../source/book.xml:4915
3825 msgid "Now, all that cruft is missing from the output! Of course, your <filename>calculator</filename> compiled program and all those logfiles are still in your working copy. Subversion is simply not reminding you that they are present and unversioned. And now with all the uninteresting noise removed from the display, you are left with more interesting items—such as that source code file <filename>data.c</filename> that you probably forgot to add to version control."
3829 #: ../source/book.xml:4923
3830 msgid "Of course, this less-verbose report of your working copy status isn't the only one available. If you actually want to see the ignored files as part of the status report, you can pass the <option>--no-ignore</option> option to Subversion:"
3834 #: ../source/book.xml:4927
3836 msgid "\n$ svn status --no-ignore\n M calc\n M calc/button.c\nI calc/calculator\n? calc/data.c\nI calc/debug_log\nI calc/debug_log.1\nI calc/debug_log.2.gz\nI calc/debug_log.3.gz\n"
3840 #: ../source/book.xml:4938
3841 msgid "As mentioned earlier, the list of file patterns to ignore is also used by <command>svn add</command> and <command>svn import</command>. Both of these operations involve asking Subversion to begin managing some set of files and directories. Rather than force the user to pick and choose which files in a tree she wishes to start versioning, Subversion uses the ignore patterns—both the global and the per-directory lists—to determine which files should not be swept into the version control system as part of a larger recursive addition or import operation. And here again, you can use the <option>--no-ignore</option> option to tell Subversion ignore its ignores list and operate on all the files and directories present."
3845 #: ../source/book.xml:4957
3846 msgid "Keyword Substitution"
3850 #: ../source/book.xml:4959
3851 msgid "Subversion has the ability to substitute <firstterm>keywords</firstterm>—pieces of useful, dynamic information about a versioned file—into the contents of the file itself. Keywords generally provide information about the last modification made to the file. Because this information changes each time the file changes, and more importantly, just <emphasis>after</emphasis> the file changes, it is a hassle for any process except the version control system to keep the data completely up-to-date. Left to human authors, the information would inevitably grow stale."
3855 #: ../source/book.xml:4970
3856 msgid "For example, say you have a document in which you would like to display the last date on which it was modified. You could burden every author of that document to, just before committing their changes, also tweak the part of the document that describes when it was last changed. But sooner or later, someone would forget to do that. Instead, simply ask Subversion to perform keyword substitution on the <literal>LastChangedDate</literal> keyword. You control where the keyword is inserted into your document by placing a <firstterm>keyword anchor</firstterm> at the desired location in the file. This anchor is just a string of text formatted as <literal>$</literal><replaceable>KeywordName</replaceable><literal>$</literal>."
3860 #: ../source/book.xml:4983
3861 msgid "All keywords are case-sensitive where they appear as anchors in files: you must use the correct capitalization in order for the keyword to be expanded. You should consider the value of the <literal>svn:keywords</literal> property to be case-sensitive too—certain keyword names will be recognized regardless of case, but this behavior is deprecated."
3865 #: ../source/book.xml:4989
3866 msgid "Subversion defines the list of keywords available for substitution. That list contains the following five keywords, some of which have aliases that you can also use:"
3870 #: ../source/book.xml:4995
3875 #: ../source/book.xml:4998
3876 msgid "This keyword describes the last time the file was known to have been changed in the repository, and is of the form <literal>$Date: 2006-07-22 21:42:37 -0700 (Sat, 22 Jul 2006) $</literal>. It may also be specified as <literal>LastChangedDate</literal>."
3880 #: ../source/book.xml:5008 ../source/book.xml:18484
3885 #: ../source/book.xml:5011
3886 msgid "This keyword describes the last known revision in which this file changed in the repository, and looks something like <literal>$Revision: 144 $</literal>. It may also be specified as <literal>LastChangedRevision</literal> or <literal>Rev</literal>."
3890 #: ../source/book.xml:5021
3895 #: ../source/book.xml:5024
3896 msgid "This keyword describes the last known user to change this file in the repository, and looks something like <literal>$Author: harry $</literal>. It may also be specified as <literal>LastChangedBy</literal>."
3900 #: ../source/book.xml:5033
3905 #: ../source/book.xml:5036
3906 msgid "This keyword describes the full URL to the latest version of the file in the repository, and looks something like <literal>$HeadURL: http://svn.collab.net/repos/trunk/README $</literal>. It may be abbreviated as <literal>URL</literal>."
3910 #: ../source/book.xml:5046
3915 #: ../source/book.xml:5049
3916 msgid "This keyword is a compressed combination of the other keywords. Its substitution looks something like <literal>$Id: calc.c 148 2006-07-28 21:30:43Z sally $</literal>, and is interpreted to mean that the file <filename>calc.c</filename> was last changed in revision 148 on the evening of July 28, 2006 by the user <literal>sally</literal>."
3920 #: ../source/book.xml:5059
3921 msgid "Several of the previous descriptions use the phrase <quote>last known</quote> or similar wording. Keep in mind that keyword expansion is a client-side operation, and your client only <quote>knows</quote> about changes which have occurred in the repository when you update your working copy to include those changes. If you never update your working copy, your keywords will never expand to different values even if those versioned files are being changed regularly in the repository."
3925 #: ../source/book.xml:5073
3926 msgid "… or maybe even a section of a book …"
3930 #: ../source/book.xml:5068
3931 msgid "Simply adding keyword anchor text to your file does nothing special. Subversion will never attempt to perform textual substitutions on your file contents unless explicitly asked to do so. After all, you might be writing a document <placeholder-1/> about how to use keywords, and you don't want Subversion to substitute your beautiful examples of un-substituted keyword anchors!"
3935 #: ../source/book.xml:5077
3936 msgid "To tell Subversion whether or not to substitute keywords on a particular file, we again turn to the property-related subcommands. The <literal>svn:keywords</literal> property, when set on a versioned file, controls which keywords will be substituted on that file. The value is a space-delimited list of the keyword names or aliases found in the previous table."
3940 #: ../source/book.xml:5084
3941 msgid "For example, say you have a versioned file named <filename>weather.txt</filename> that looks like this:"
3945 #: ../source/book.xml:5087
3947 msgid "\nHere is the latest report from the front lines.\n$LastChangedDate$\n$Rev$\nCumulus clouds are appearing more frequently as summer approaches.\n"
3951 #: ../source/book.xml:5093
3952 msgid "With no <literal>svn:keywords</literal> property set on that file, Subversion will do nothing special. Now, let's enable substitution of the <literal>LastChangedDate</literal> keyword."
3956 #: ../source/book.xml:5097
3958 msgid "\n$ svn propset svn:keywords \"Date Author\" weather.txt\nproperty 'svn:keywords' set on 'weather.txt'\n$\n"
3962 #: ../source/book.xml:5102
3963 msgid "Now you have made a local property modification on the <filename>weather.txt</filename> file. You will see no changes to the file's contents (unless you made some of your own prior to setting the property). Notice that the file contained a keyword anchor for the <literal>Rev</literal> keyword, yet we did not include that keyword in the property value we set. Subversion will happily ignore requests to substitute keywords that are not present in the file, and will not substitute keywords that are not present in the <literal>svn:keywords</literal> property value."
3967 #: ../source/book.xml:5112
3968 msgid "Immediately after you commit this property change, Subversion will update your working file with the new substitute text. Instead of seeing your keyword anchor <literal>$LastChangedDate$</literal>, you'll see its substituted result. That result also contains the name of the keyword, and continues to be bounded by the dollar sign (<literal>$</literal>) characters. And as we predicted, the <literal>Rev</literal> keyword was not substituted because we didn't ask for it to be."
3972 #: ../source/book.xml:5121
3973 msgid "Note also that we set the <literal>svn:keywords</literal> property to <quote>Date Author</quote> yet the keyword anchor used the alias <literal>$LastChangedDate$</literal> and still expanded correctly."
3977 #: ../source/book.xml:5125
3979 msgid "\nHere is the latest report from the front lines.\n$LastChangedDate: 2006-07-22 21:42:37 -0700 (Sat, 22 Jul 2006) $\n$Rev$\nCumulus clouds are appearing more frequently as summer approaches.\n"
3983 #: ../source/book.xml:5131
3984 msgid "If someone else now commits a change to <filename>weather.txt</filename>, your copy of that file will continue to display the same substituted keyword value as before—until you update your working copy. At that time the keywords in your <filename>weather.txt</filename> file will be re-substituted with information that reflects the most recent known commit to that file."
3988 #: ../source/book.xml:5140
3989 msgid "Where's $GlobalRev$?"
3993 #: ../source/book.xml:5142
3994 msgid "New users are often confused by how the <literal>$Rev$</literal> keyword works. Since the repository has a single, globally increasing revision number, many people assume that it is this number which is reflected by the <literal>$Rev$</literal> keyword's value. But <literal>$Rev$</literal> expands to show the last revision in which the file <emphasis>changed</emphasis>, not the last revision to which it was updated. Understanding this clears the confusion, but frustration often remains—without the support of a Subversion keyword to do so, how can you automatically get the global revision number into your files?"
3998 #: ../source/book.xml:5154
3999 msgid "To do this, you need external processing. Subversion ships with a tool called <command>svnversion</command> which was designed for just this purpose. <command>svnversion</command> crawls your working copy and generates as output the revision(s) it finds. You can use this program, plus some additional tooling, to embed that revision information into your files. For more information on <command>svnversion</command>, see <xref linkend=\"svn.ref.svnversion\"/>."
4003 #: ../source/book.xml:5163
4004 msgid "Subversion 1.2 introduced a new variant of the keyword syntax which brought additional, useful—though perhaps atypical—functionality. You can now tell Subversion to maintain a fixed length (in terms of the number of bytes consumed) for the substituted keyword. By using a double-colon (<literal>::</literal>) after the keyword name, followed by a number of space characters, you define that fixed width. When Subversion goes to substitute your keyword for the keyword and its value, it will essentially replace only those space characters, leaving the overall width of the keyword field unchanged. If the substituted value is shorter than the defined field width, there will be extra padding characters (spaces) at the end of the substituted field; if it is too long, it is truncated with a special hash (<literal>#</literal>) character just before the final dollar sign terminator."
4008 #: ../source/book.xml:5179
4009 msgid "For example, say you have a document in which you have some section of tabular data reflecting the document's Subversion keywords. Using the original Subversion keyword substitution syntax, your file might look something like:"
4013 #: ../source/book.xml:5184
4015 msgid "\n$Rev$: Revision of last commit\n$Author$: Author of last commit\n$Date$: Date of last commit\n"
4019 #: ../source/book.xml:5189
4020 msgid "Now, that looks nice and tabular at the start of things. But when you then commit that file (with keyword substitution enabled, of course), you see:"
4024 #: ../source/book.xml:5192
4026 msgid "\n$Rev: 12 $: Revision of last commit\n$Author: harry $: Author of last commit\n$Date: 2006-03-15 02:33:03 -0500 (Wed, 15 Mar 2006) $: Date of last commit\n"
4030 #: ../source/book.xml:5197
4031 msgid "The result is not so beautiful. And you might be tempted to then adjust the file after the substitution so that it again looks tabular. But that only holds as long as the keyword values are the same width. If the last committed revision rolls into a new place value (say, from 99 to 100), or if another person with a longer username commits the file, stuff gets all crooked again. However, if you are using Subversion 1.2 or better, you can use the new fixed-length keyword syntax, define some field widths that seem sane, and now your file might look like this:"
4035 #: ../source/book.xml:5207
4037 msgid "\n$Rev:: $: Revision of last commit\n$Author:: $: Author of last commit\n$Date:: $: Date of last commit\n"
4041 #: ../source/book.xml:5212
4042 msgid "You commit this change to your file. This time, Subversion notices the new fixed-length keyword syntax, and maintains the width of the fields as defined by the padding you placed between the double-colon and the trailing dollar sign. After substitution, the width of the fields is completely unchanged—the short values for <literal>Rev</literal> and <literal>Author</literal> are padded with spaces, and the long <literal>Date</literal> field is truncated by a hash character:"
4046 #: ../source/book.xml:5221
4048 msgid "\n$Rev:: 13 $: Revision of last commit\n$Author:: harry $: Author of last commit\n$Date:: 2006-03-15 0#$: Date of last commit\n"
4052 #: ../source/book.xml:5226
4053 msgid "The use of fixed-length keywords is especially handy when performing substitutions into complex file formats that themselves use fixed-length fields for data, or for which the stored size of a given data field is overbearingly difficult to modify from outside the format's native application (such as for Microsoft Office documents)."
4057 #: ../source/book.xml:5233
4058 msgid "Be aware that because the width of a keyword field is measured in bytes, the potential for corruption of multi-byte values exists. For example, a username which contains some multi-byte UTF-8 characters might suffer truncation in the middle of the string of bytes which make up one of those characters. The result will be a mere truncation when viewed at the byte level, but will likely appear as a string with an incorrect or garbled final character when viewed as UTF-8 text. It is conceivable that certain applications, when asked to load the file, would notice the broken UTF-8 text and deem the entire file corrupt, refusing to operate on the file altogether. So, when limiting keywords to a fixed size, choose a size that allows for this type of byte-wise expansion."
4062 #: ../source/book.xml:5255
4067 #: ../source/book.xml:5257
4068 msgid "Subversion's copy-modify-merge version control model lives and dies on its data merging algorithms, specifically on how well those algorithms perform when trying to resolve conflicts caused by multiple users modifying the same file concurrently. Subversion itself provides only one such algorithm, a three-way differencing algorithm which is smart enough to handle data at a granularity of a single line of text. Subversion also allows you to supplement its content merge processing with external differencing utilities (as described in <xref linkend=\"svn.advanced.externaldifftools.diff3\"/>), some of which may do an even better job, perhaps providing granularity of a word or a single character of text. But common among those algorithms is that they generally work only on text files. The landscape starts to look pretty grim when you start talking about content merges of non-textual file formats. And when you can't find a tool that can handle that type of merging, you begin to run into problems with the copy-modify-merge model."
4072 #: ../source/book.xml:5274
4073 msgid "Let's look at a real-life example of where this model runs aground. Harry and Sally are both graphic designers working on the same project, a bit of marketing collateral for an automobile mechanic. Central to the design of a particular poster is an image of a car in need of some body work, stored in a file using the PNG image format. The poster's layout is almost finished, and both Harry and Sally are pleased with the particular photo they chose for their damaged car—a baby blue 1967 Ford Mustang with an unfortunate bit of crumpling on the left front fender."
4077 #: ../source/book.xml:5284
4078 msgid "Now, as is common in graphic design work, there's a change in plans which causes the car's color to be a concern. So Sally updates her working copy to <literal>HEAD</literal>, fires up her photo editing software, and sets about tweaking the image so that the car is now cherry red. Meanwhile, Harry, feeling particularly inspired that day, decides that the image would have greater impact if the car also appears to have suffered greater impact. He, too, updates to <literal>HEAD</literal>, and then draws some cracks on the vehicle's windshield. He manages to finish his work before Sally finishes hers, and after admiring the fruits of his undeniable talent, commits the modified image. Shortly thereafter, Sally is finished with the car's new finish, and tries to commit her changes. But, as expected, Subversion fails the commit, informing Sally that now her version of the image is out of date."
4082 #: ../source/book.xml:5299
4083 msgid "Here's where the difficulty sets in. Were Harry and Sally making changes to a text file, Sally would simply update her working copy, receiving Harry's changes in the process. In the worst possible case, they would have modified the same region of the file, and Sally would have to work out by hand the proper resolution to the conflict. But these aren't text files—they are binary images. And while it's a simple matter to describe what one would expect the results of this content merge to be, there is precious little chance that any software exists which is smart enough to examine the common baseline image that each of these graphic artists worked against, the changes that Harry made, and the changes that Sally made, and spit out an image of a busted-up red Mustang with a cracked windshield!"
4087 #: ../source/book.xml:5320
4088 msgid "Communication wouldn't have been such bad medicine for Harry and Sally's Hollywood namesakes, either, for that matter."
4092 #: ../source/book.xml:5313
4093 msgid "Clearly, things would have gone more smoothly if Harry and Sally had serialized their modifications to the image—if, say, Harry had waited to draw his windshield cracks on Sally's now-red car, or if Sally had tweaked the color of a car whose windshield was already cracked. As is discussed in <xref linkend=\"svn.basic.vsn-models.copy-merge\"/>, most of these types of problems go away entirely where perfect communication between Harry and Sally exists. <placeholder-1/> But as one's version control system is, in fact, one form of communication, it follows that having that software facilitate the serialization of non-parallelizable editing efforts is no bad thing. This where Subversion's implementation of the lock-modify-unlock model steps into the spotlight. This is where we talk about Subversion's <firstterm>locking</firstterm> feature, which is similar to the <quote>reserved checkouts</quote> mechanisms of other version control systems."
4097 #: ../source/book.xml:5332
4098 msgid "Subversion's locking feature serves two main purposes:"
4102 #: ../source/book.xml:5336
4103 msgid "<emphasis>Serializing access to a versioned object</emphasis>. By allowing a user to programmatically claim the exclusive right to change to a file in the repository, that user can be reasonably confident that energy invested on unmergeable changes won't be wasted—his commit of those changes will succeed."
4107 #: ../source/book.xml:5344
4108 msgid "<emphasis>Aiding communication</emphasis>. By alerting other users that serialization is in effect for a particular versioned object, those other users can reasonably expect that the object is about to be changed by someone else, and they, too, can avoid wasting their time and energy on unmergeable changes that won't be committable due to eventual out-of-dateness."
4112 #: ../source/book.xml:5356
4113 msgid "Subversion does not currently allow locks on directories."
4117 #: ../source/book.xml:5353
4118 msgid "When referring to Subversion's locking feature, one is actually talking about a fairly diverse collection of behaviors which include the ability to lock a versioned file <placeholder-1/> (claiming the exclusive right to modify the file), to unlock that file (yielding that exclusive right to modify), to see reports about which files are locked and by whom, to annotate files for which locking before editing is strongly advised, and so on. In this section, we'll cover all of these facets of the larger locking feature."
4122 #: ../source/book.xml:5365
4123 msgid "The three meanings of <quote>lock</quote>"
4127 #: ../source/book.xml:5367
4128 msgid "In this section, and almost everywhere in this book, the words <quote>lock</quote> and <quote>locking</quote> describe a mechanism for mutual exclusion between users to avoid clashing commits. Unfortunately, there are two other sorts of <quote>lock</quote> with which Subversion, and therefore this book, sometimes needs to be concerned."
4132 #: ../source/book.xml:5373
4133 msgid "The first is <firstterm>working copy locks</firstterm>, used internally by Subversion to prevent clashes between multiple Subversion clients operating on the same working copy. This is the sort of lock indicated by an <computeroutput>L</computeroutput> in the third column of <command>svn status</command> output, and removed by the <command>svn cleanup</command> command, as described in <xref linkend=\"svn.tour.cleanup\"/>."
4137 #: ../source/book.xml:5380
4138 msgid "Secondly, there are <firstterm>database locks</firstterm>, used internally by the Berkeley DB backend to prevent clashes between multiple programs trying to access the database. This is the sort of lock whose unwanted persistence after an error can cause a repository to be <quote>wedged</quote>, as described in <xref linkend=\"svn.reposadmin.maint.recovery\"/>."
4142 #: ../source/book.xml:5386
4143 msgid "You can generally forget about these other kinds of locks until something goes wrong that requires you to care about them. In this book, <quote>lock</quote> means the first sort unless the contrary is either clear from context or explicitly stated."
4147 #: ../source/book.xml:5395
4148 msgid "Creating locks"
4152 #: ../source/book.xml:5397
4153 msgid "In the Subversion repository, a <firstterm>lock</firstterm> is a piece of metadata which grants exclusive access to one user to change a file. This user is said to be the <firstterm>lock owner</firstterm>. Each lock also has a unique identifier, typically a long string of characters, known as the <firstterm>lock token</firstterm>. The repository manages locks, ultimately handling their creation, enforcement, and removal. If any commit transaction attempts to modify or delete a locked file (or delete one of the parent directories of the file), the repository will demand two pieces of information—that the client performing the commit be authenticated as the lock owner, and that the lock token has been provided as part of the commit process as a sort of proof that client knows which lock it is using."
4157 #: ../source/book.xml:5412
4158 msgid "To demonstrate lock creation, let's refer back to our example of multiple graphic designers working with on the same binary image files. Harry has decided to change a JPEG image. To prevent other people from committing changes to the file while he is modifying it (as well as alerting them that he is about to change it), he locks the file in the repository using the <command>svn lock</command> command."
4162 #: ../source/book.xml:5419
4164 msgid "\n$ svn lock banana.jpg -m \"Editing file for tomorrow's release.\"\n'banana.jpg' locked by user 'harry'.\n$\n"
4168 #: ../source/book.xml:5424
4169 msgid "There are a number of new things demonstrated in the previous example. First, notice that Harry passed the <option>--message (-m)</option> option to <command>svn lock</command>. Similar to <command>svn commit</command>, the <command>svn lock</command> command can take comments (either via <option>--message (-m)</option> or <option>--file (-F)</option>) to describe the reason for locking the file. Unlike <command>svn commit</command>, however, <command>svn lock</command> will not demand a message by launching your preferred text editor. Lock comments are optional, but still recommended to aid communication."
4173 #: ../source/book.xml:5435
4174 msgid "Secondly, 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 <command>svn update</command> and reattempt the locking command. The locking command would also have failed if the file already been locked by someone else."
4178 #: ../source/book.xml:5443
4179 msgid "As you can see, the <command>svn lock</command> command prints confirmation of the successful lock. At this point, the fact that the file is locked becomes apparent in the output of the <command>svn status</command> and <command>svn info</command> reporting subcommands."
4183 #: ../source/book.xml:5448
4185 msgid "\n$ svn status\n K banana.jpg\n\n$ svn info banana.jpg\nPath: banana.jpg\nName: banana.jpg\nURL: http://svn.example.com/repos/project/banana.jpg\nRepository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec\nRevision: 2198\nNode Kind: file\nSchedule: normal\nLast Changed Author: frank\nLast Changed Rev: 1950\nLast Changed Date: 2006-03-15 12:43:04 -0600 (Wed, 15 Mar 2006)\nText Last Updated: 2006-06-08 19:23:07 -0500 (Thu, 08 Jun 2006)\nProperties Last Updated: 2006-06-08 19:23:07 -0500 (Thu, 08 Jun 2006)\nChecksum: 3b110d3b10638f5d1f4fe0f436a5a2a5\nLock Token: opaquelocktoken:0c0f600b-88f9-0310-9e48-355b44d4a58e\nLock Owner: harry\nLock Created: 2006-06-14 17:20:31 -0500 (Wed, 14 Jun 2006)\nLock Comment (1 line):\nEditing file for tomorrow's release.\n\n$\n"
4189 #: ../source/book.xml:5474
4190 msgid "That the <command>svn info</command> command, which does not contact the repository when run against working copy paths, can display the lock token reveals an important fact about lock tokens—that they are cached in the working copy. The presence of the lock token is critical. It gives the working copy authorization to make use of the lock later on. Also, the <command>svn status</command> command shows a <literal>K</literal> next to the file (short for locKed), indicating that the lock token is present."
4194 #: ../source/book.xml:5485
4195 msgid "Regarding lock tokens"
4199 #: ../source/book.xml:5487
4200 msgid "A lock token isn't an authentication token, so much as an <emphasis>authorization</emphasis> token. The token isn't a protected secret. In fact, a lock's unique token is discoverable by anyone who runs <command>svn info URL</command>. 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."
4204 #: ../source/book.xml:5496
4205 msgid "For example, suppose you lock a file using a computer at your office, but leave work for the day before you finish your changes to that file. It should not be possible to accidentally commit changes to that same file from your home computer later that evening simply 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 <firstterm>break</firstterm> the lock and re-lock the file.)"
4209 #: ../source/book.xml:5508
4210 msgid "Now that Harry has locked <filename>banana.jpg</filename>, Sally is unable to change or delete that file:"
4214 #: ../source/book.xml:5510
4216 msgid "\n$ svn delete banana.jpg\nD banana.jpg\n$ svn commit -m \"Delete useless file.\"\nDeleting banana.jpg\nsvn: Commit failed (details follow):\nsvn: DELETE of\n'/repos/project/!svn/wrk/64bad3a9-96f9-0310-818a-df4224ddc35d/banana.jpg':\n423 Locked (http://svn.example.com)\n$\n"
4220 #: ../source/book.xml:5521
4221 msgid "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:"
4225 #: ../source/book.xml:5525
4227 msgid "\n$ svn status\nM K banana.jpg\n$ svn commit -m \"Make banana more yellow\"\nSending banana.jpg\nTransmitting file data .\nCommitted revision 2201.\n$ svn status\n$\n"
4231 #: ../source/book.xml:5535
4232 msgid "Notice that after the commit is finished, <command>svn status</command> shows that the lock token is no longer present in working copy. This is the standard behavior of <command>svn commit</command>—it searches the working copy (or list of targets, if you provide such a list) for local modifications, and sends all the lock tokens it encounters during this walk to the server as part of the commit transaction. After the commit completes successfully, all of the repository locks that were mentioned are released—<emphasis>even on files that weren't committed</emphasis>. This is meant to discourage users from being sloppy about locking, or from holding locks for too long. If Harry haphazardly locks thirty files in a directory named <filename>images</filename> because he's unsure of which files he needs to change, yet only only changes four of those files, when he runs <command>svn commit images</command>, the process will still release all thirty locks."
4236 #: ../source/book.xml:5552
4237 msgid "This behavior of automatically releasing locks can be overridden with the <option>--no-unlock</option> option to <command>svn commit</command>. 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. You can also make this your default behavior by setting the <literal>no-unlock</literal> runtime configuration option (see <xref linkend=\"svn.advanced.confarea\"/>)."
4241 #: ../source/book.xml:5560
4242 msgid "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 <command>svn unlock</command> command:"
4246 #: ../source/book.xml:5563
4248 msgid "\n$ svn unlock banana.c\n'banana.c' unlocked.\n"
4252 #: ../source/book.xml:5571
4253 msgid "Discovering locks"
4257 #: ../source/book.xml:5573
4258 msgid "When a commit fails due to someone else's locks, it's fairly easy to learn about them. The easiest of these is <command>svn status --show-updates</command>:"
4262 #: ../source/book.xml:5576
4264 msgid "\n$ svn status -u\nM 23 bar.c\nM O 32 raisin.jpg\n * 72 foo.h\nStatus against revision: 105\n$\n"
4268 #: ../source/book.xml:5584
4269 msgid "In this example, Sally can see not only that her copy of <filename>foo.h</filename> is out-of-date, but that one of the two modified files she plans to commit is locked in the repository. The <literal>O</literal> symbol stands for <quote>Other</quote>, meaning that a lock exists on the file, and was created by somebody else. If she were to attempt a commit, the lock on <filename>raisin.jpg</filename> would prevent it. Sally is left wondering who made the lock, when, and why. Once again, <command>svn info</command> has the answers:"
4273 #: ../source/book.xml:5594
4275 msgid "\n$ svn info http://svn.example.com/repos/project/raisin.jpg\nPath: raisin.jpg\nName: raisin.jpg\nURL: http://svn.example.com/repos/project/raisin.jpg\nRepository UUID: edb2f264-5ef2-0310-a47a-87b0ce17a8ec\nRevision: 105\nNode Kind: file\nLast Changed Author: sally\nLast Changed Rev: 32\nLast Changed Date: 2006-01-25 12:43:04 -0600 (Sun, 25 Jan 2006)\nLock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b\nLock Owner: harry\nLock Created: 2006-02-16 13:29:18 -0500 (Thu, 16 Feb 2006)\nLock Comment (1 line):\nNeed to make a quick tweak to this image.\n$\n"
4279 #: ../source/book.xml:5612
4280 msgid "Just as <command>svn info</command> 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 <command>svn info</command> 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, <command>svn info</command> on a working copy path will show no lock information at all). If the main argument to <command>svn info</command> is a URL, then the information reflects the latest version of an object in the repository, and any mention of a lock describes the current lock on the object."
4284 #: ../source/book.xml:5625
4285 msgid "So in this particular example, Sally can see that Harry locked the file on February 16th to <quote>make a quick tweak</quote>. 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."
4289 #: ../source/book.xml:5636
4290 msgid "Breaking and stealing locks"
4294 #: ../source/book.xml:5638
4295 msgid "A repository lock isn't sacred—in Subversion's default configuration state, locks can be released not only by the person who created them, but by anyone at all. When somebody other than the original lock creator destroys a lock, we refer to this as <firstterm>breaking</firstterm> the lock."
4299 #: ../source/book.xml:5644
4300 msgid "From the administrator's chair, it's simple to break locks. The <command>svnlook</command> and <command>svnadmin</command> programs have the ability to display and remove locks directly from the repository. (For more information about these tools, see <xref linkend=\"svn.reposadmin.maint.tk\"/>.)"
4304 #: ../source/book.xml:5650
4306 msgid "\n$ svnadmin lslocks /usr/local/svn/repos\nPath: /project2/images/banana.jpg\nUUID Token: opaquelocktoken:c32b4d88-e8fb-2310-abb3-153ff1236923\nOwner: frank\nCreated: 2006-06-15 13:29:18 -0500 (Thu, 15 Jun 2006)\nExpires: \nComment (1 line):\nStill improving the yellow color.\n\nPath: /project/raisin.jpg\nUUID Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b\nOwner: harry\nCreated: 2006-02-16 13:29:18 -0500 (Thu, 16 Feb 2006)\nExpires: \nComment (1 line):\nNeed to make a quick tweak to this image.\n\n$ svnadmin rmlocks /usr/local/svn/repos /project/raisin.jpg\nRemoved lock on '/project/raisin.jpg'.\n$\n"
4310 #: ../source/book.xml:5672
4311 msgid "The more interesting option is allowing users to break each other's locks over the network. To do this, Sally simply needs to pass the <option>--force</option> to the unlock command:"
4315 #: ../source/book.xml:5676
4317 msgid "\n$ svn status -u\nM 23 bar.c\nM O 32 raisin.jpg\n * 72 foo.h\nStatus against revision: 105\n$ svn unlock raisin.jpg\nsvn: 'raisin.jpg' is not locked in this working copy\n$ svn info raisin.jpg | grep URL\nURL: http://svn.example.com/repos/project/raisin.jpg\n$ svn unlock http://svn.example.com/repos/project/raisin.jpg\nsvn: Unlock request failed: 403 Forbidden (http://svn.example.com)\n$ svn unlock --force http://svn.example.com/repos/project/raisin.jpg\n'raisin.jpg' unlocked.\n$\n"
4321 #: ../source/book.xml:5692
4322 msgid "Now, Sally's initial attempt to unlock failed because she ran <command>svn unlock</command> 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 <command>svn unlock</command>. 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 <option>--force</option>, the authentication and authorization requirements are ignored, and the remote lock is broken."
4326 #: ../source/book.xml:5702
4327 msgid "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 <command>svn unlock --force</command> and then <command>svn lock</command> 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 <firstterm>steal</firstterm> the lock, which involves breaking and re-locking the file all in one atomic step. To do this, Sally passes the <option>--force</option> option to <command>svn lock</command>:"
4331 #: ../source/book.xml:5713
4333 msgid "\n$ svn lock raisin.jpg\nsvn: Lock request failed: 423 Locked (http://svn.example.com)\n$ svn lock --force raisin.jpg\n'raisin.jpg' locked by user 'sally'.\n$\n"
4337 #: ../source/book.xml:5720
4338 msgid "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 <firstterm>defunct</firstterm>. 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 <command>svn status</command> to contact the repository:"
4342 #: ../source/book.xml:5729
4344 msgid "\n$ svn status\n K raisin.jpg\n$ svn status -u\n B 32 raisin.jpg\n$ svn update\n B raisin.jpg\n$ svn status\n$\n"
4348 #: ../source/book.xml:5739
4349 msgid "If the repository lock was broken, then <command>svn status --show-updates</command> displays a <literal>B</literal> (Broken) symbol next to the file. If a new lock exists in place of the old one, then a <literal>T</literal> (sTolen) symbol is shown. Finally, <command>svn update</command> notices any defunct lock tokens and removes them from the working copy."
4353 #: ../source/book.xml:5748
4354 msgid "Locking Policies"
4358 #: ../source/book.xml:5750
4359 msgid "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 runs rampant 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."
4363 #: ../source/book.xml:5760
4364 msgid "Subversion defaults to the <quote>softer</quote> approach, but still allows administrators to create stricter enforcement policies through the use of hook scripts. In particular, the <filename>pre-lock</filename> and <filename>pre-unlock</filename> 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 <filename>post-lock</filename> and <filename>post-unlock</filename> hooks are also available, and can be used to send email after locking actions. To learn more about repository hooks, see <xref linkend=\"svn.reposadmin.create.hooks\"/>."
4368 #: ../source/book.xml:5778
4369 msgid "Lock Communication"
4373 #: ../source/book.xml:5780
4374 msgid "We've seen how <command>svn lock</command> and <command>svn unlock</command> can be used to create, release, break, and steal locks. This satisfies the goal of serializing commit access to a file. But what about the larger problem of preventing wasted time?"
4378 #: ../source/book.xml:5785
4379 msgid "For example, suppose Harry locks an image file and then begins editing it. Meanwhile, miles away, Sally wants to do the same thing. She doesn't think to run <command>svn status --show-updates</command>, so she has no idea that Harry has already locked the file. She spends hours editing the file, and when she tries to commit her change, she discovers that either the file is locked or that she's out-of-date. Regardless, her changes aren't mergeable with Harry's. One of these two people has to throw away their work, and a lot of time has been wasted."
4383 #: ../source/book.xml:5795
4384 msgid "Subversion's solution to this problem is to provide a mechanism to remind users that a file ought to be locked <emphasis>before</emphasis> the editing begins. The mechanism is a special property, <literal>svn:needs-lock</literal>. If that property is attached to a file (regardless of its value, which is irrelevant), then Subversion will try to use filesystem-level permissions to make the file read-only—unless, of course, the user has explicitly locked the file. When a lock token is present (as a result of running <command>svn lock</command>), the file becomes read-write. When the lock is released, the file becomes read-only again."
4388 #: ../source/book.xml:5807
4389 msgid "The theory, then, is that if the image file has this property attached, then Sally would immediately notice something is strange when she opens the file for editing: many applications alert users immediately when a read-only file is opened for editing, and nearly all would prevent her from saving changes to the file. This reminds her to lock the file before editing, whereby she discovers the pre-existing lock:"
4393 #: ../source/book.xml:5815
4395 msgid "\n$ /usr/local/bin/gimp raisin.jpg\ngimp: error: file is read-only!\n$ ls -l raisin.jpg\n-r--r--r-- 1 sally sally 215589 Jun 8 19:23 raisin.jpg\n$ svn lock raisin.jpg\nsvn: Lock request failed: 423 Locked (http://svn.example.com)\n$ svn info http://svn.example.com/repos/project/raisin.jpg | grep Lock\nLock Token: opaquelocktoken:fc2b4dee-98f9-0310-abf3-653ff3226e6b\nLock Owner: harry\nLock Created: 2006-06-08 07:29:18 -0500 (Thu, 08 June 2006)\nLock Comment (1 line):\nMaking some tweaks. Locking for the next two hours.\n$\n"
4399 #: ../source/book.xml:5831
4400 msgid "Users and administrators alike are encouraged to attach the <literal>svn:needs-lock</literal> property to any file which cannot be contextually merged. This is the primary technique for encouraging good locking habits and preventing wasted effort."
4404 #: ../source/book.xml:5837
4405 msgid "Note that this property is a communication tool which works independently from the locking system. In other words, any file can be locked, whether or not this property is present. And conversely, the presence of this property doesn't make the repository require a lock when committing."
4409 #: ../source/book.xml:5851
4410 msgid "Except, perhaps, a classic Vulcan mind-meld."
4414 #: ../source/book.xml:5843
4415 msgid "Unfortunately, the system isn't flawless. It's possible that even when a file has the property, the read-only reminder won't always work. Sometimes applications misbehave and <quote>hijack</quote> the read-only file, silently allowing users to edit and save the file anyway. There's not much that Subversion can do in this situation—at the end of the day, there's simply no substitution for good interpersonal communication. <placeholder-1/>"
4419 #: ../source/book.xml:5860
4420 msgid "Externals Definitions"
4424 #: ../source/book.xml:5862
4425 msgid "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 set up such a scenario by hand—using <command>svn checkout</command> 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."
4429 #: ../source/book.xml:5872
4430 msgid "Fortunately, Subversion provides support for <firstterm>externals definitions</firstterm>. An externals definition is a mapping of a local directory to the URL—and ideally a particular revision—of a versioned directory. In Subversion, you declare externals definitions in groups using the <literal>svn:externals</literal> property. You can create or modify this property using <command>svn propset</command> or <command>svn propedit</command> (see <xref linkend=\"svn.advanced.props.manip\"/>). 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), optional revision flags, and fully qualified, absolute Subversion repository URLs."
4434 #: ../source/book.xml:5885
4436 msgid "\n$ svn propget svn:externals calc\nthird-party/sounds http://sounds.red-bean.com/repos\nthird-party/skins http://skins.red-bean.com/repositories/skinproj\nthird-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker\n"
4440 #: ../source/book.xml:5891
4441 msgid "The convenience of the <literal>svn:externals</literal> 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 check out the external working copies."
4445 #: ../source/book.xml:5900
4446 msgid "The relative target subdirectories of externals definitions <emphasis>must not</emphasis> already exist on your or other users' systems—Subversion will create them when it checks out the external working copy."
4450 #: ../source/book.xml:5905
4451 msgid "Note the previous externals definition example. When someone checks out a working copy of the <filename>calc</filename> directory, Subversion also continues to check out the items found in its externals definition."
4455 #: ../source/book.xml:5909
4457 msgid "\n$ svn checkout http://svn.example.com/repos/calc\nA calc\nA calc/Makefile\nA calc/integer.c\nA calc/button.c\nChecked out revision 148.\n\nFetching external item into calc/third-party/sounds\nA calc/third-party/sounds/ding.ogg\nA calc/third-party/sounds/dong.ogg\nA calc/third-party/sounds/clang.ogg\n…\nA calc/third-party/sounds/bang.ogg\nA calc/third-party/sounds/twang.ogg\nChecked out revision 14.\n\nFetching external item into calc/third-party/skins\n…\n"
4461 #: ../source/book.xml:5929
4462 msgid "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 <literal>svn:externals</literal> property, Subversion will synchronize the checked-out items against the changed externals definition when you next run <command>svn update</command>. The same thing will happen when others update their working copies and receive your changes to the externals definition."
4466 #: ../source/book.xml:5938
4467 msgid "Because the <literal>svn:externals</literal> property has a multiline value, we strongly recommend that you use <command>svn propedit</command> instead of <command>svn propset</command>."
4471 #: ../source/book.xml:5944
4472 msgid "You should seriously consider using explicit revision numbers in all of your externals definitions. Doing so means that you get to decide when to pull down a different snapshot of external information, and exactly which snapshot to pull. Besides avoiding the surprise of getting changes to third-party repositories that you might not have any control over, using explicit revision numbers also means that as you backdate your working copy to a previous revision, your externals definitions will also revert to the way they looked in that previous revision, which in turn means that the external working copies will be updated to match they way <emphasis>they</emphasis> looked back when your repository was at that previous revision. For software projects, this could be the difference between a successful and a failed build of an older snapshot of your complex codebase."
4476 #: ../source/book.xml:5960
4477 msgid "The <command>svn status</command> command also recognizes externals definitions, displaying a status code of <literal>X</literal> 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."
4481 #: ../source/book.xml:5966
4482 msgid "The support that exists for externals definitions in Subversion is less than ideal, though. First, an externals definition can only point to directories, not files. Second, the externals definition cannot point to relative paths (paths like <filename>../../skins/myskin</filename>). Third, the working copies created via the externals definition support are still disconnected from the primary working copy (on whose versioned directories the <literal>svn:externals</literal> property was actually set). And Subversion still only truly operates on non-disjoint working copies. So, for example, if you want to commit changes that you've made in one or more of those external working copies, you must run <command>svn commit</command> explicitly on those working copies—committing on the primary working copy will not recurse into any external ones."
4486 #: ../source/book.xml:5981
4487 msgid "Also, since the definitions themselves use absolute URLs, moving or copying a directory to which they are attached will not affect what gets checked out as an external (though the relative local target subdirectory will, of course, move with renamed directory). This can be confusing—even frustrating—in certain situations. For example, say you have a top-level directory named <filename>my-project</filename>, and you've created an externals definition on one of its subdirectories (<filename>my-project/some-dir</filename>) which tracks the latest revision of another of its subdirectories (<filename>my-project/external-dir</filename>)."
4491 #: ../source/book.xml:5993
4493 msgid "\n$ svn checkout http://svn.example.com/projects .\nA my-project\nA my-project/some-dir\nA my-project/external-dir\n…\nFetching external item into 'my-project/some-dir/subdir'\nChecked out external at revision 11.\n\nChecked out revision 11.\n$ svn propget svn:externals my-project/some-dir\nsubdir http://svn.example.com/projects/my-project/external-dir\n\n$\n"
4497 #: ../source/book.xml:6008
4498 msgid "Now you use <command>svn move</command> to rename the <filename>my-project</filename> directory. At this point, your externals definition will still refer to a path under the <filename>my-project</filename> directory, even though that directory no longer exists."
4502 #: ../source/book.xml:6013
4504 msgid "\n$ svn move -q my-project renamed-project\n$ svn commit -m \"Rename my-project to renamed-project.\"\nDeleting my-project\nAdding my-renamed-project\n\nCommitted revision 12.\n$ svn update\n\nFetching external item into 'renamed-project/some-dir/subdir'\nsvn: Target path does not exist\n$\n"
4508 #: ../source/book.xml:6026
4509 msgid "Also, the absolute URLs that externals definitions use can cause problems with repositories that are available via multiple URL schemes. For example, if your Subversion server is configured to allow everyone to check out the repository over <literal>http://</literal> or <literal>https://</literal>, but only allow commits to come in via <literal>https://</literal>, you have an interesting problem on your hands. If your externals definitions use the <literal>http://</literal> form of the repository URLs, you won't be able to commit anything from the working copies created by those externals. On the other hand, if they use the <literal>https://</literal> form of the URLs, anyone who might be checking out via <literal>http://</literal> because their client doesn't support <literal>https://</literal> will be unable to fetch the external items. Be aware, too, that if you need to re-parent your working copy (using <command>svn switch --relocate</command>), externals definitions will <emphasis>not</emphasis> also be re-parented."
4513 #: ../source/book.xml:6044
4514 msgid "Finally, there might be times when you would prefer that <command>svn</command> subcommands would not recognize, or otherwise operate upon, the external working copies. In those instances, you can pass the <option>--ignore-externals</option> option to the subcommand."
4518 #: ../source/book.xml:6055
4519 msgid "Peg and Operative Revisions"
4523 #: ../source/book.xml:6057
4524 msgid "We copy, move, rename, and completely replace files and directories on our computers all the time. And your version control system shouldn't get in the way of your doing these things with your version-controlled files and directories, either. Subversion's file management support is quite liberating, affording almost as much flexibility for versioned files as you'd expect when manipulating your unversioned ones. But that flexibility means that across the lifetime of your repository, a given versioned object might have many paths, and a given path might represent several entirely different versioned objects. And this introduces a certain level of complexity to your interactions with those paths and objects."
4528 #: ../source/book.xml:6070
4529 msgid "Subversion is pretty smart about noticing when an object's version history includes such <quote>changes of address</quote>. For example, if you ask for the revision history log of a particular file that was renamed last week, Subversion happily provides all those logs—the revision in which the rename itself happened, plus the logs of relevant revisions both before and after that rename. So, most of the time, you don't even have to think about such things. But occasionally, Subversion needs your help to clear up ambiguities."
4533 #: ../source/book.xml:6079
4534 msgid "The simplest example of this occurs when a directory or file is deleted from version control, and then a new directory or file is created with the same name and added to version control. Clearly the thing you deleted and the thing you later added aren't the same thing. They merely happen to have had the same path, <filename>/trunk/object</filename> for example. What, then, does it mean to ask Subversion about the history of <filename>/trunk/object</filename>? Are you asking about the thing currently at that location, or the old thing you deleted from that location? Are you asking about the operations that have happened to <emphasis>all</emphasis> the objects that have ever lived at that path? Clearly, Subversion needs a hint about what you really want."
4538 #: ../source/book.xml:6099
4539 msgid "<quote>You're not supposed to name it. Once you name it, you start getting attached to it.</quote>—Mike Wazowski"
4543 #: ../source/book.xml:6092
4544 msgid "And thanks to moves, versioned object history can get far more twisted than that, even. For example, you might have a directory named <filename>concept</filename>, containing some nascent software project you've been toying with. Eventually, though, that project matures to the point that the idea seems to actually have some wings, so you do the unthinkable and decide to give the project a name. <placeholder-1/> Let's say you called your software Frabnaggilywort. At this point, it makes sense to rename the directory to reflect the project's new name, so <filename>concept</filename> is renamed to <filename>frabnaggilywort</filename>. Life goes on, Frabnaggilywort releases a 1.0 version, and is downloaded and used daily by hordes of people aiming to improve their lives."
4548 #: ../source/book.xml:6109
4549 msgid "It's a nice story, really, but it doesn't end there. Entrepreneur that you are, you've already got another think in the tank. So you make a new directory, <filename>concept</filename>, and the cycle begins again. In fact, the cycle begins again many times over the years, each time starting with that old <filename>concept</filename> directory, then sometimes seeing that directory renamed as the idea cures, sometimes seeing it deleted when you scrap the idea. Or, to get really sick, maybe you rename <filename>concept</filename> to something else for a while, but later rename the thing back to <filename>concept</filename> for some reason."
4553 #: ../source/book.xml:6121
4554 msgid "In scenarios like these, attempting to instruct Subversion to work with these re-used paths can be a little like instructing a motorist in Chicago's West Suburbs to drive east down Roosevelt Road and turn left onto Main Street. In a mere twenty minutes, you can cross <quote>Main Street</quote> in Wheaton, Glen Ellyn, and Lombard. And no, they aren't the same street. Our motorist—and our Subversion—need a little more detail in order to do the right thing."
4558 #: ../source/book.xml:6129
4559 msgid "In version 1.1, Subversion introduced a way for you to tell it exactly which Main Street you meant. It's called the <firstterm>peg revision</firstterm>, and it is a revision provided to Subversion for the sole purpose of identifying a unique line of history. Because at most one versioned object may occupy a path at any given time—or, more precisely, in any one revision—the combination of a path and a peg revision is all that is needed to refer to a specific line of history. Peg revisions are specified to the Subversion command-line client using <firstterm>at syntax</firstterm>, so called because the syntax involves appending an <quote>at sign</quote> (<literal>@</literal>) and the peg revision to the end of the path with which the revision is associated."
4563 #: ../source/book.xml:6151
4564 msgid "606 N. Main Street, Wheaton, Illinois, is the home of the Wheaton History Center. Get it—<quote>History Center</quote>? It seemed appropriate…."
4568 #: ../source/book.xml:6142
4569 msgid "But what of the <option>--revision (-r)</option> of which we've spoken so much in this book? That revision (or set of revisions) is called the <firstterm>operative revision</firstterm> (or <firstterm>operative revision range</firstterm>). Once a particular line of history has been identified using a path and peg revision, Subversion performs the requested operation using the operative revision(s). To map this to our Chicagoland streets analogy, if we are told to go to 606 N. Main Street in Wheaton, <placeholder-1/> we can think of <quote>Main Street</quote> as our path and <quote>Wheaton</quote> as our peg revision. These two pieces of information identify a unique path which can travelled (north or south on Main Street), and will keep us from travelling up and down the wrong Main Street in search of our destination. Now we throw in <quote>606 N.</quote> as our operative revision, of sorts, and we know <emphasis>exactly</emphasis> where to go."
4573 #: ../source/book.xml:6164
4574 msgid "The peg revision algorithm"
4578 #: ../source/book.xml:6166
4579 msgid "The Subversion command-line performs the peg revision algorithm any time it needs to resolve possible ambiguities in the paths and revisions provided to it. Here's an example of such an invocation:"
4583 #: ../source/book.xml:6171
4588 #: ../source/book.xml:6171
4589 msgid "OPERATIVE-REV"
4593 #: ../source/book.xml:6171
4598 #: ../source/book.xml:6170
4600 msgid "\n$ svn <placeholder-1/> -r <placeholder-2/> item@<placeholder-3/>\n"
4604 #: ../source/book.xml:6173
4605 msgid "If <replaceable>OPERATIVE-REV</replaceable> is older than <replaceable>PEG-REV</replaceable>, then the algorithm is as follows:"
4609 #: ../source/book.xml:6178
4610 msgid "Locate <replaceable>item</replaceable> in the revision identified by <replaceable>PEG-REV</replaceable>. There can be only one such object."
4614 #: ../source/book.xml:6183
4615 msgid "Trace the object's history backwards (through any possible renames) to its ancestor in the revision <replaceable>OPERATIVE-REV</replaceable>."
4619 #: ../source/book.xml:6188
4620 msgid "Perform the requested action on that ancestor, wherever it is located, or whatever its name might be or have been at that time."
4624 #: ../source/book.xml:6193
4625 msgid "But what if <replaceable>OPERATIVE-REV</replaceable> is <emphasis>younger</emphasis> than <replaceable>PEG-REV</replaceable>? Well, that adds some complexity to the theoretical problem of locating the path in <replaceable>OPERATIVE-REV</replaceable>, because the path's history could have forked multiple times (thanks to copy operations) between <replaceable>PEG-REV</replaceable> and <replaceable>OPERATIVE-REV</replaceable>. And that's not all—Subversion doesn't store enough information to performantly trace an object's history forward, anyway. So the algorithm is a little different:"
4629 #: ../source/book.xml:6206
4630 msgid "Locate <replaceable>item</replaceable> in the revision identified by <replaceable>OPERATIVE-REV</replaceable>. There can be only one such object."
4634 #: ../source/book.xml:6211
4635 msgid "Trace the object's history backwards (through any possible renames) to its ancestor in the revision <replaceable>PEG-REV</replaceable>."
4639 #: ../source/book.xml:6216
4640 msgid "Verify that the object's location (path-wise) in <replaceable>PEG-REV</replaceable> is the same as it is in <replaceable>OPERATIVE-REV</replaceable>. If that's the case, then at least the two locations are known to be directly related, so perform the requested action on the location in <replaceable>OPERATIVE-REV</replaceable>. Otherwise, relatedness was not established, so error out with a loud complaint that no viable location was found. (Someday, we expect that Subversion will be able to handle this usage scenario with more flexibility and grace.)"
4644 #: ../source/book.xml:6229
4645 msgid "Note that even when you don't explicitly supply a peg revision or operative revision, they are still present. For your convenience, the default peg revision is <literal>BASE</literal> for working copy items and <literal>HEAD</literal> for repository URLs. And when no operative revision is provided, it defaults to being the same revision as the peg revision."
4649 #: ../source/book.xml:6237
4650 msgid "Say that long ago we created our repository, and in revision 1 added our first <filename>concept</filename> directory, plus an <filename>IDEA</filename> file in that directory talking about the concept. After several revisions in which real code was added and tweaked, we, in revision 20, renamed this directory to <filename>frabnaggilywort</filename>. By revision 27, we had a new concept, a new <filename>concept</filename> directory to hold it, and a new <filename>IDEA</filename> file to describe it. And then five years and twenty thousand revisions flew by, just like they would in any good romance story."
4654 #: ../source/book.xml:6247
4655 msgid "Now, years later, we wonder what the <filename>IDEA</filename> file looked like back in revision 1. But Subversion needs to know if we are asking about how the <emphasis>current</emphasis> file looked back in revision 1, or if we are asking for the contents of whatever file lived at <filename>concepts/IDEA</filename> in revision 1. Certainly those questions have different answers, and because of peg revisions, you can ask either of them. To find out how the current <filename>IDEA</filename> file looked in that old revision, you run:"
4659 #: ../source/book.xml:6257
4661 msgid "\n$ svn cat -r 1 concept/IDEA \nsvn: Unable to find repository location for 'concept/IDEA' in revision 1\n"
4665 #: ../source/book.xml:6261
4666 msgid "Of course, in this example, the current <filename>IDEA</filename> file didn't exist yet in revision 1, so Subversion gives an error. The command above is shorthand for a longer notation which explicitly lists a peg revision. The expanded notation is:"
4670 #: ../source/book.xml:6266
4672 msgid "\n$ svn cat -r 1 concept/IDEA@BASE\nsvn: Unable to find repository location for 'concept/IDEA' in revision 1\n"
4676 #: ../source/book.xml:6270
4677 msgid "And when executed, it has the expected results."
4681 #: ../source/book.xml:6271
4682 msgid "The perceptive reader is probably wondering at this point if the peg revision syntax causes problems for working copy paths or URLs that actually have at signs in them. After all, how does <command>svn</command> know whether <literal>news@11</literal> is the name of a directory in my tree, or just a syntax for <quote>revision 11 of <filename>news</filename></quote>? Thankfully, while <command>svn</command> will always assume the latter, there is a trivial workaround. You need only append an at sign to the end of the path, such as <literal>news@11@</literal>. <command>svn</command> only cares about the last at sign in the argument, and it is not considered illegal to omit a literal peg revision specifier after that at sign. This workaround even applies to paths that end in an at sign—you would use <literal>filename@@</literal> to talk about a file named <filename>filename@</filename>."
4686 #: ../source/book.xml:6287
4687 msgid "Let's ask the other question, then—in revision 1, what were the contents of whatever file occupied the address <filename>concepts/IDEA</filename> at the time? We'll use an explicit peg revision to help us out."
4691 #: ../source/book.xml:6291
4693 msgid "\n$ svn cat concept/IDEA@1\nThe idea behind this project is to come up with a piece of software\nthat can frab a naggily wort. Frabbing naggily worts is tricky\nbusiness, and doing it incorrectly can have serious ramifications, so\nwe need to employ over-the-top input validation and data verification\nmechanisms.\n"
4697 #: ../source/book.xml:6299
4698 msgid "Notice that we didn't provide an operative revision this time. That's because when no operative revision is specified, Subversion assumes a default operative revision that's the same as the peg revision."
4702 #: ../source/book.xml:6303
4703 msgid "As you can see, the output from our operation appears to be correct. The text even mentions frabbing naggily worts, so this is almost certainly the file which describes the software now called Frabnaggilywort. In fact, we can verify this using the combination of an explicit peg revision and explicit operative revision. We know that in <literal>HEAD</literal>, the Frabnaggilywort project is located in the <filename>frabnaggilywort</filename> directory. So we specify that we want to see how the line of history identified in <literal>HEAD</literal> as the path <filename>frabnaggilywort/IDEA</filename> looked in revision 1."
4707 #: ../source/book.xml:6315
4709 msgid "\n$ svn cat -r 1 frabnaggilywort/IDEA@HEAD\nThe idea behind this project is to come up with a piece of software\nthat can frab a naggily wort. Frabbing naggily worts is tricky\nbusiness, and doing it incorrectly can have serious ramifications, so\nwe need to employ over-the-top input validation and data verification\nmechanisms.\n"
4713 #: ../source/book.xml:6323
4714 msgid "And the peg and operative revisions need not be so trivial, either. For example, say <filename>frabnaggilywort</filename> had been deleted from <literal>HEAD</literal>, but we know it existed in revision 20, and we want to see the diffs for its <filename>IDEA</filename> file between revisions 4 and 10. We can use the peg revision 20 in conjunction with the URL that would have held Frabnaggilywort's <filename>IDEA</filename> file in revision 20, and then use 4 and 10 as our operative revision range."
4718 #: ../source/book.xml:6332
4720 msgid "\n$ svn diff -r 4:10 http://svn.red-bean.com/projects/frabnaggilywort/IDEA@20\nIndex: frabnaggilywort/IDEA\n===================================================================\n--- frabnaggilywort/IDEA\t(revision 4)\n+++ frabnaggilywort/IDEA\t(revision 10)\n@@ -1,5 +1,5 @@\n-The idea behind this project is to come up with a piece of software\n-that can frab a naggily wort. Frabbing naggily worts is tricky\n-business, and doing it incorrectly can have serious ramifications, so\n-we need to employ over-the-top input validation and data verification\n-mechanisms.\n+The idea behind this project is to come up with a piece of\n+client-server software that can remotely frab a naggily wort.\n+Frabbing naggily worts is tricky business, and doing it incorrectly\n+can have serious ramifications, so we need to employ over-the-top\n+input validation and data verification mechanisms.\n"
4724 #: ../source/book.xml:6350
4725 msgid "Fortunately, most folks aren't faced with such complex situations. But when you are, remember that peg revisions are that extra hint Subversion needs to clear up ambiguity."
4729 #: ../source/book.xml:6359
4730 msgid "Network Model"
4734 #: ../source/book.xml:6361
4735 msgid "At some point, you're going to need to understand how your Subversion client communicates with its server. Subversion's networking layer is abstracted, meaning that Subversion clients exhibit the same general behaviors no matter what sort of server they are operating against. Whether speaking the HTTP protocol (<literal>http://</literal>) with the Apache HTTP Server or speaking the custom Subversion protocol (<literal>svn://</literal>) with <command>svnserve</command>, the basic network model is the same. In this section, we'll explain the basics of that network model, including how Subversion manages authentication and authorization matters."
4739 #: ../source/book.xml:6376
4740 msgid "Requests and Responses"
4744 #: ../source/book.xml:6378
4745 msgid "The Subversion client spends most of its time managing working copies. When it needs information from a remote repository, however, it makes a network request, and the server responds with an appropriate answer. The details of the network protocol are hidden from the user—the client attempts to access a URL, and depending on the URL scheme, a particular protocol is used to contact the server (see <xref linkend=\"svn.basic.in-action.wc.sb-1\"/>)."
4749 #: ../source/book.xml:6386
4750 msgid "Run <command>svn --version</command> to see which URL schemes and protocols the client knows how to use."
4754 #: ../source/book.xml:6390
4755 msgid "When the server process receives a client request, it often demands that the client identify itself. It issues an authentication challenge to the client, and the client responds by providing <firstterm>credentials</firstterm> back to the server. Once authentication is complete, the server responds with the original information the client asked for. Notice that this system is different from systems like CVS, where the client pre-emptively offers credentials (<quote>logs in</quote>) to the server before ever making a request. In Subversion, the server <quote>pulls</quote> credentials by challenging the client at the appropriate moment, rather than the client <quote>pushing</quote> them. This makes certain operations more elegant. For example, if a server is configured to allow anyone in the world to read a repository, then the server will never issue an authentication challenge when a client attempts to <command>svn checkout</command>."
4759 #: ../source/book.xml:6406
4760 msgid "If the particular network requests issued by the client result in a new revision being created in the repository, (e.g. <command>svn commit</command>), then Subversion uses the authenticated username associated with those requests as the author of the revision. That is, the authenticated user's name is stored as the value of the <literal>svn:author</literal> property on the new revision (see <xref linkend=\"svn.ref.properties\"/>). If the client was not authenticated (in other words, the server never issued an authentication challenge), then the revision's <literal>svn:author</literal> property is empty."
4764 #: ../source/book.xml:6422
4765 msgid "Client Credentials Caching"
4769 #: ../source/book.xml:6424
4770 msgid "Many servers are configured to require authentication on every request. This would be a big annoyance to users, if they were forced to type their passwords over and over again. Fortunately, the Subversion client has a remedy for this—a built-in system for caching authentication credentials on disk. By default, whenever the command-line client successfully responds to a server's authentication challenge, it saves the credentials in the user's private runtime configuration area (<filename>~/.subversion/auth/</filename> on Unix-like systems or <filename>%APPDATA%/Subversion/auth/</filename> on Windows; see <xref linkend=\"svn.advanced.confarea\"/> for more details about the runtime configuration system). Successful credentials are cached on disk, keyed on a combination of the server's hostname, port, and authentication realm."
4774 #: ../source/book.xml:6439
4775 msgid "When the client receives an authentication challenge, it first looks for the appropriate credentials in the user's disk cache. If seemingly suitable credentials are not present, or if the cached credentials ultimately fail to authenticate, then the client will, by default, fall back to prompting the user for the necessary information."
4779 #: ../source/book.xml:6445
4780 msgid "The security-conscious reader will suspect immediately that there is reason for concern here. <quote>Caching passwords on disk? That's terrible! You should never do that!</quote>"
4784 #: ../source/book.xml:6449
4785 msgid "The Subversion developers recognize the legitimacy of such concerns, and so Subversion works with available mechanisms provided by the operating system and environment to try to minimize the risk of leaking this information. Here's a breakdown of what this means for users on the most common platforms:"
4789 #: ../source/book.xml:6457
4790 msgid "On Windows 2000 and later, the Subversion client uses standard Windows cryptography services to encrypt the password on disk. Because the encryption key is managed by Windows and is tied to the user's own login credentials, only the user can decrypt the cached password. (Note that if the user's Windows account password is reset by an administrator, all of the cached passwords become undecipherable. The Subversion client will behave as if they don't exist, prompting for passwords when required.)"
4794 #: ../source/book.xml:6469
4795 msgid "Similarly, on Mac OS X, the Subversion client stores all repository passwords in the login keyring (managed by the Keychain service), which is protected by the user's account password. User preference settings can impose additional policies, such as requiring the user's account password be entered each time the Subversion password is used."
4799 #: ../source/book.xml:6478
4800 msgid "For other Unix-like operating systems, no standard <quote>keychain</quote> services exist. However, the <filename>auth/</filename> caching area is still permission-protected so that only the user (owner) can read data from it, not the world at large. The operating system's own file permissions protect the passwords."
4804 #: ../source/book.xml:6486
4805 msgid "Of course, for the truly paranoid, none of these mechanisms meets the test of perfection. So for those folks willing to sacrifice convenience for the ultimate security, Subversion provides various ways of disabling its credentials caching system altogether."
4809 #: ../source/book.xml:6491
4810 msgid "To disable caching for a single command, pass the <option>--no-auth-cache</option> option:"
4814 #: ../source/book.xml:6493
4816 msgid "\n$ svn commit -F log_msg.txt --no-auth-cache\nAuthentication realm: <svn://host.example.com:3690> example realm\nUsername: joe\nPassword for 'joe':\n\nAdding newfile\nTransmitting file data .\nCommitted revision 2324.\n\n# password was not cached, so a second commit still prompts us\n\n$ svn delete newfile\n$ svn commit -F new_msg.txt\nAuthentication realm: <svn://host.example.com:3690> example realm\nUsername: joe\n…\n"
4820 #: ../source/book.xml:6511
4821 msgid "Or, if you want to disable credential caching permanently, you can edit the <filename>config</filename> file in your runtime configuration area, and set the <option>store-auth-creds</option> option to <literal>no</literal>. This will prevent the storing of credentials used in any Subversion interactions you perform on the affected computer. This can be extended to cover all users on the computer, too, by modifying the system-wide runtime configuration area (described in <xref linkend=\"svn.advanced.confarea.layout\"/>)."
4825 #: ../source/book.xml:6520
4827 msgid "\n[auth]\nstore-auth-creds = no\n"
4831 #: ../source/book.xml:6524
4832 msgid "Sometimes users will want to remove specific credentials from the disk cache. To do this, you need to navigate into the <filename>auth/</filename> area and manually delete the appropriate cache file. Credentials are cached in individual files; if you look inside each file, you will see keys and values. The <literal>svn:realmstring</literal> key describes the particular server realm that the file is associated with:"
4836 #: ../source/book.xml:6532
4838 msgid "\n$ ls ~/.subversion/auth/svn.simple/\n5671adf2865e267db74f09ba6f872c28\n3893ed123b39500bca8a0b382839198e\n5c3c22968347b390f349ff340196ed39\n\n$ cat ~/.subversion/auth/svn.simple/5671adf2865e267db74f09ba6f872c28\n\nK 8\nusername\nV 3\njoe\nK 8\npassword\nV 4\nblah\nK 15\nsvn:realmstring\nV 45\n<https://svn.domain.com:443> Joe's repository\nEND\n"
4842 #: ../source/book.xml:6554
4843 msgid "Once you have located the proper cache file, just delete it."
4847 #: ../source/book.xml:6567
4848 msgid "Again, a common mistake is to misconfigure a server so that it never issues an authentication challenge. When users pass <option>--username</option> and <option>--password</option> options to the client, they're surprised to see that they're never used, i.e. new revisions still appear to have been committed anonymously!"
4852 #: ../source/book.xml:6556
4853 msgid "One last word about <command>svn</command>'s authentication behavior, specifically regarding the <option>--username</option> and <option>--password</option> options. Many client subcommands accept these options, but it is important to understand using these options does <emphasis>not</emphasis> automatically send credentials to the server. As discussed earlier, the server <quote>pulls</quote> credentials from the client when it deems necessary; the client cannot <quote>push</quote> them at will. If a username and/or password are passed as options, they will only be presented to the server if the server requests them. <placeholder-1/> These options are typically used to authenticate as a different user than Subversion would have chosen by default (such as your system login name), or when trying to avoid interactive prompting (such as when calling <command>svn</command> from a script)."
4857 #: ../source/book.xml:6580
4858 msgid "Here is a final summary that describes how a Subversion client behaves when it receives an authentication challenge."
4862 #: ../source/book.xml:6585
4863 msgid "First, the client checks whether the user specified any credentials as command-line options (<option>--username</option> and/or <option>--password</option>). If not, or if these options fail to authenticate successfully, then"
4867 #: ../source/book.xml:6592
4868 msgid "the client looks up the server's hostname, port, and realm in the runtime <filename>auth/</filename> area, to see if the user already has the appropriate credentials cached. If not, or if the cached credentials fail to authenticate, then"
4872 #: ../source/book.xml:6599
4873 msgid "finally, the client resorts to prompting the user (unless instructed not to do so via the <option>--non-interactive</option> option or its client-specific equivalents)."
4877 #: ../source/book.xml:6605
4878 msgid "If the client successfully authenticates by any of the methods listed above, it will attempt to cache the credentials on disk (unless the user has disabled this behavior, as mentioned earlier)."
4882 #: ../source/book.xml:6619
4883 msgid "Branching and Merging"
4887 #: ../source/book.xml:6622
4892 #: ../source/book.xml:6624
4893 msgid "君子务本 (It is upon the Trunk that a gentleman works.)"
4897 #: ../source/book.xml:6628
4898 msgid "Branching, tagging, and merging are concepts common to almost all version control systems. If you're not familiar with these ideas, we provide a good introduction in this chapter. If you are familiar, then hopefully you'll find it interesting to see how Subversion implements these ideas."
4902 #: ../source/book.xml:6633
4903 msgid "Branching is a fundamental part of version control. If you're going to allow Subversion to manage your data, then this is a feature you'll eventually come to depend on. This chapter assumes that you're already familiar with Subversion's basic concepts (<xref linkend=\"svn.basic\"/>)."
4907 #: ../source/book.xml:6643
4908 msgid "What's a Branch?"
4912 #: ../source/book.xml:6645
4913 msgid "Suppose it's your job to maintain a document for a division in your company, a handbook of some sort. One day a different division asks you for the same handbook, but with a few parts <quote>tweaked</quote> for them, since they do things slightly differently."
4917 #: ../source/book.xml:6650
4918 msgid "What do you do in this situation? You do the obvious thing: you make a second copy of your document, and begin maintaining the two copies separately. As each department asks you to make small changes, you incorporate them into one copy or the other."
4922 #: ../source/book.xml:6655
4923 msgid "You often want to make the same change to both copies. For example, if you discover a typo in the first copy, it's very likely that the same typo exists in the second copy. The two documents are almost the same, after all; they only differ in small, specific ways."
4927 #: ../source/book.xml:6660
4928 msgid "This is the basic concept of a <firstterm>branch</firstterm>—namely, a line of development that exists independently of another line, yet still shares a common history if you look far enough back in time. A branch always begins life as a copy of something, and moves on from there, generating its own history (see <xref linkend=\"svn.branchmerge.whatis.dia-1\"/>)."
4932 #: ../source/book.xml:6668
4933 msgid "Branches of development"
4937 #: ../source/book.xml:6676
4938 msgid "Subversion has commands to help you maintain parallel branches of your files and directories. It allows you to create branches by copying your data, and remembers that the copies are related to one another. It also helps you duplicate changes from one branch to another. Finally, it can make portions of your working copy reflect different branches, so that you can <quote>mix and match</quote> different lines of development in your daily work."
4942 #: ../source/book.xml:6690
4943 msgid "Using Branches"
4947 #: ../source/book.xml:6692
4948 msgid "At this point, you should understand how each commit creates an entire new filesystem tree (called a <quote>revision</quote>) in the repository. If not, go back and read about revisions in <xref linkend=\"svn.basic.in-action.revs\"/>."
4952 #: ../source/book.xml:6696
4953 msgid "For this chapter, we'll go back to the same example from <xref linkend=\"svn.basic\"/>. Remember that you and your collaborator, Sally, are sharing a repository that contains two projects, <filename>paint</filename> and <filename>calc</filename>. Notice that in <xref linkend=\"svn.branchmerge.using.dia-1\"/>, however, each project directory now contains subdirectories named <filename>trunk</filename> and <filename>branches</filename>. The reason for this will soon become clear."
4957 #: ../source/book.xml:6706
4958 msgid "Starting repository layout"
4962 #: ../source/book.xml:6714
4963 msgid "As before, assume that Sally and you both have working copies of the <quote>calc</quote> project. Specifically, you each have a working copy of <filename>/calc/trunk</filename>. All the files for the project are in this subdirectory rather than in <filename>/calc</filename> itself, because your team has decided that <filename>/calc/trunk</filename> is where the <quote>main line</quote> of development is going to take place."
4967 #: ../source/book.xml:6722
4968 msgid "Let's say that you've been given the task of implementing a radical new project feature. It will take a long time to write, and will affect all the files in the project. The problem here is that you don't want to interfere with Sally, who is in the process of fixing small bugs here and there. She's depending on the fact that the latest version of the project (in <filename>/calc/trunk</filename>) is always usable. If you start committing your changes bit-by-bit, you'll surely break things for Sally."
4972 #: ../source/book.xml:6731
4973 msgid "One strategy is to crawl into a hole: you and Sally can stop sharing information for a week or two. That is, start gutting and reorganizing all the files in your working copy, but don't commit or update until you're completely finished with the task. There are a number of problems with this, though. First, it's not very safe. Most people like to save their work to the repository frequently, should something bad accidentally happen to their working copy. Second, it's not very flexible. If you do your work on different computers (perhaps you have a working copy of <filename>/calc/trunk</filename> on two different machines), you'll need to manually copy your changes back and forth, or just do all the work on a single computer. By that same token, it's difficult to share your changes-in-progress with anyone else. A common software development <quote>best practice</quote> is to allow your peers to review your work as you go. If nobody sees your intermediate commits, you lose potential feedback. Finally, when you're finished with all your changes, you might find it very difficult to re-merge your final work with the rest of the company's main body of code. Sally (or others) may have made many other changes in the repository that are difficult to incorporate into your working copy—especially if you run <command>svn update</command> after weeks of isolation."
4977 #: ../source/book.xml:6754
4978 msgid "The better solution is to create your own branch, or line of development, in the repository. This allows you to save your half-broken work frequently without interfering with others, yet you can still selectively share information with your collaborators. You'll see exactly how this works later on."
4982 #: ../source/book.xml:6763
4983 msgid "Creating a Branch"
4987 #: ../source/book.xml:6765
4988 msgid "Creating a branch is very simple—you make a copy of the project in the repository using the <command>svn copy</command> command. Subversion is not only able to copy single files, but whole directories as well. In this case, you want to make a copy of the <filename>/calc/trunk</filename> directory. Where should the new copy live? Wherever you wish—it's a matter of project policy. Let's say that your team has a policy of creating branches in the <filename>/calc/branches</filename> area of the repository, and you want to name your branch <literal>my-calc-branch</literal>. You'll want to create a new directory, <filename>/calc/branches/my-calc-branch</filename>, which begins its life as a copy of <filename>/calc/trunk</filename>."
4992 #: ../source/book.xml:6780
4993 msgid "There are two different ways to make a copy. We'll demonstrate the messy way first, just to make the concept clear. To begin, check out a working copy of the project's root directory, <filename>/calc</filename>:"
4997 #: ../source/book.xml:6784
4999 msgid "\n$ svn checkout http://svn.example.com/repos/calc bigwc\nA bigwc/trunk/\nA bigwc/trunk/Makefile\nA bigwc/trunk/integer.c\nA bigwc/trunk/button.c\nA bigwc/branches/\nChecked out revision 340.\n"
5003 #: ../source/book.xml:6793
5004 msgid "Making a copy is now simply a matter of passing two working-copy paths to the <command>svn copy</command> command:"
5008 #: ../source/book.xml:6796
5010 msgid "\n$ cd bigwc\n$ svn copy trunk branches/my-calc-branch\n$ svn status\nA + branches/my-calc-branch\n"
5014 #: ../source/book.xml:6802
5015 msgid "In this case, the <command>svn copy</command> command recursively copies the <filename>trunk</filename> working directory to a new working directory, <filename>branches/my-calc-branch</filename>. As you can see from the <command>svn status</command> command, the new directory is now scheduled for addition to the repository. But also notice the <quote>+</quote> sign next to the letter A. This indicates that the scheduled addition is a <emphasis>copy</emphasis> of something, not something new. When you commit your changes, Subversion will create <filename>/calc/branches/my-calc-branch</filename> in the repository by copying <filename>/calc/trunk</filename>, rather than resending all of the working copy data over the network:"
5019 #: ../source/book.xml:6816
5021 msgid "\n$ svn commit -m \"Creating a private branch of /calc/trunk.\"\nAdding branches/my-calc-branch\nCommitted revision 341.\n"
5025 #: ../source/book.xml:6821
5026 msgid "And now here's the easier method of creating a branch, which we should have told you about in the first place: <command>svn copy</command> is able to operate directly on two URLs."
5030 #: ../source/book.xml:6825
5032 msgid "\n$ svn copy http://svn.example.com/repos/calc/trunk \\\n http://svn.example.com/repos/calc/branches/my-calc-branch \\\n -m \"Creating a private branch of /calc/trunk.\"\n\nCommitted revision 341.\n"
5036 #: ../source/book.xml:6840
5037 msgid "Subversion does not support copying between different repositories. When using URLs with <command>svn copy</command> or <command>svn move</command>, you can only copy items within the same repository."
5041 #: ../source/book.xml:6832
5042 msgid "From the repository's point of view, there's really no difference between these two methods. Both procedures create a new directory in revision 341, and the new directory is a copy of <filename>/calc/trunk</filename>. This is shown in <xref linkend=\"svn.branchmerge.using.create.dia-1\"/>. Notice that the second method, however, performs an <emphasis>immediate</emphasis> commit in constant time. <placeholder-1/> It's an easier procedure, because it doesn't require you to check out a large portion of the repository. In fact, this technique doesn't even require you to have a working copy at all. This is the way most users create branches."
5046 #: ../source/book.xml:6851
5047 msgid "Repository with new copy"
5051 #: ../source/book.xml:6861
5052 msgid "Cheap Copies"
5056 #: ../source/book.xml:6863
5057 msgid "Subversion's repository has a special design. When you copy a directory, you don't need to worry about the repository growing huge—Subversion doesn't actually duplicate any data. Instead, it creates a new directory entry that points to an <emphasis>existing</emphasis> tree. If you're a Unix user, this is the same concept as a hard-link. As further changes are made to files and directories beneath the copied directory, Subversion continues to employ this hard-link concept where it can. It only duplicates data when it is necessary to disambiguate different versions of objects."
5061 #: ../source/book.xml:6874
5062 msgid "This is why you'll often hear Subversion users talk about <quote>cheap copies</quote>. It doesn't matter how large the directory is—it takes a very tiny, constant amount of time to make a copy of it. In fact, this feature is the basis of how commits work in Subversion: each revision is a <quote>cheap copy</quote> of the previous revision, with a few items lazily changed within. (To read more about this, visit Subversion's website and read about the <quote>bubble up</quote> method in Subversion's design documents.)"
5066 #: ../source/book.xml:6884
5067 msgid "Of course, these internal mechanics of copying and sharing data are hidden from the user, who simply sees copies of trees. The main point here is that copies are cheap, both in time and space. If you create a branch entirely within the repository (by running <command>svn copy URL1 URL2</command>), it's a quick, constant-time operation. Make branches as often as you want."
5071 #: ../source/book.xml:6896
5072 msgid "Working with Your Branch"
5076 #: ../source/book.xml:6898
5077 msgid "Now that you've created a branch of the project, you can check out a new working copy to start using it:"
5081 #: ../source/book.xml:6900
5083 msgid "\n$ svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch\nA my-calc-branch/Makefile\nA my-calc-branch/integer.c\nA my-calc-branch/button.c\nChecked out revision 341.\n"
5087 #: ../source/book.xml:6907
5088 msgid "There's nothing special about this working copy; it simply mirrors a different directory in the repository. When you commit changes, however, Sally won't see them when she updates, because her working copy is of <filename>/calc/trunk</filename>. (Be sure to read <xref linkend=\"svn.branchmerge.switchwc\"/> later in this chapter: the <command>svn switch</command> command is an alternate way of creating a working copy of a branch.)"
5092 #: ../source/book.xml:6914
5093 msgid "Let's pretend that a week goes by, and the following commits happen:"
5097 #: ../source/book.xml:6918
5098 msgid "You make a change to <filename>/calc/branches/my-calc-branch/button.c</filename>, which creates revision 342."
5102 #: ../source/book.xml:6924
5103 msgid "You make a change to <filename>/calc/branches/my-calc-branch/integer.c</filename>, which creates revision 343."
5107 #: ../source/book.xml:6930
5108 msgid "Sally makes a change to <filename>/calc/trunk/integer.c</filename>, which creates revision 344."
5112 #: ../source/book.xml:6936
5113 msgid "There are now two independent lines of development, shown in <xref linkend=\"svn.branchmerge.using.work.dia-1\"/>, happening on <filename>integer.c</filename>."
5117 #: ../source/book.xml:6941
5118 msgid "The branching of one file's history"
5122 #: ../source/book.xml:6949
5123 msgid "Things get interesting when you look at the history of changes made to your copy of <filename>integer.c</filename>:"
5127 #: ../source/book.xml:6952
5129 msgid "\n$ pwd\n/home/user/my-calc-branch\n\n$ svn log -v integer.c\n------------------------------------------------------------------------\nr343 | user | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines\nChanged paths:\n M /calc/branches/my-calc-branch/integer.c\n\n* integer.c: frozzled the wazjub.\n\n------------------------------------------------------------------------\nr341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines\nChanged paths:\n A /calc/branches/my-calc-branch (from /calc/trunk:340)\n\nCreating a private branch of /calc/trunk.\n\n------------------------------------------------------------------------\nr303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines\nChanged paths:\n M /calc/trunk/integer.c\n\n* integer.c: changed a docstring.\n\n------------------------------------------------------------------------\nr98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines\nChanged paths:\n M /calc/trunk/integer.c\n\n* integer.c: adding this file to the project.\n\n------------------------------------------------------------------------\n"
5133 #: ../source/book.xml:6987
5134 msgid "Notice that Subversion is tracing the history of your branch's <filename>integer.c</filename> all the way back through time, even traversing the point where it was copied. It shows the creation of the branch as an event in the history, because <filename>integer.c</filename> was implicitly copied when all of <filename>/calc/trunk/</filename> was copied. Now look what happens when Sally runs the same command on her copy of the file:"
5138 #: ../source/book.xml:6995
5140 msgid "\n$ pwd\n/home/sally/calc\n\n$ svn log -v integer.c\n------------------------------------------------------------------------\nr344 | sally | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines\nChanged paths:\n M /calc/trunk/integer.c\n\n* integer.c: fix a bunch of spelling errors.\n\n------------------------------------------------------------------------\nr303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines\nChanged paths:\n M /calc/trunk/integer.c\n\n* integer.c: changed a docstring.\n\n------------------------------------------------------------------------\nr98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines\nChanged paths:\n M /calc/trunk/integer.c\n\n* integer.c: adding this file to the project.\n\n------------------------------------------------------------------------\n"
5144 #: ../source/book.xml:7023
5145 msgid "Sally sees her own revision 344 change, but not the change you made in revision 343. As far as Subversion is concerned, these two commits affected different files in different repository locations. However, Subversion <emphasis>does</emphasis> show that the two files share a common history. Before the branch-copy was made in revision 341, they used to be the same file. That's why you and Sally both see the changes made in revisions 303 and 98."
5149 #: ../source/book.xml:7035
5150 msgid "The Key Concepts Behind Branches"
5154 #: ../source/book.xml:7037
5155 msgid "There are two important lessons that you should remember from this section. First, Subversion has no internal concept of a branch—it only knows how to make copies. When you copy a directory, the resulting directory is only a <quote>branch</quote> because <emphasis>you</emphasis> attach that meaning to it. You may think of the directory differently, or treat it differently, but to Subversion it's just an ordinary directory that happens to carry some extra historical information. Second, because of this copy mechanism, Subversion's branches exist as <emphasis>normal filesystem directories</emphasis> in the repository. This is different from other version control systems, where branches are typically defined by adding extra-dimensional <quote>labels</quote> to collections of files."
5159 #: ../source/book.xml:7059
5160 msgid "Copying Changes Between Branches"
5164 #: ../source/book.xml:7061
5165 msgid "Now you and Sally are working on parallel branches of the project: you're working on a private branch, and Sally is working on the <firstterm>trunk</firstterm>, or main line of development."
5169 #: ../source/book.xml:7065
5170 msgid "For projects that have a large number of contributors, it's common for most people to have working copies of the trunk. Whenever someone needs to make a long-running change that is likely to disrupt the trunk, a standard procedure is to create a private branch and commit changes there until all the work is complete."
5174 #: ../source/book.xml:7071
5175 msgid "So, the good news is that you and Sally aren't interfering with each other. The bad news is that it's very easy to drift <emphasis>too</emphasis> far apart. Remember that one of the problems with the <quote>crawl in a hole</quote> strategy is that by the time you're finished with your branch, it may be near-impossible to merge your changes back into the trunk without a huge number of conflicts."
5179 #: ../source/book.xml:7078
5180 msgid "Instead, you and Sally might continue to share changes as you work. It's up to you to decide which changes are worth sharing; Subversion gives you the ability to selectively <quote>copy</quote> changes between branches. And when you're completely finished with your branch, your entire set of branch changes can be copied back into the trunk."
5184 #: ../source/book.xml:7087
5185 msgid "Copying Specific Changes"
5189 #: ../source/book.xml:7089
5190 msgid "In the previous section, we mentioned that both you and Sally made changes to <filename>integer.c</filename> on different branches. If you look at Sally's log message for revision 344, you can see that she fixed some spelling errors. No doubt, your copy of the same file still has the same spelling errors. It's likely that your future changes to this file will be affecting the same areas that have the spelling errors, so you're in for some potential conflicts when you merge your branch someday. It's better, then, to receive Sally's change now, <emphasis>before</emphasis> you start working too heavily in the same places."
5194 #: ../source/book.xml:7100
5195 msgid "It's time to use the <command>svn merge</command> command. This command, it turns out, is a very close cousin to the <command>svn diff</command> command (which you read about in <xref linkend=\"svn.tour\"/>). Both commands are able to compare any two objects in the repository and describe the differences. For example, you can ask <command>svn diff</command> to show you the exact change made by Sally in revision 344:"
5199 #: ../source/book.xml:7108
5201 msgid "\n$ svn diff -c 344 http://svn.example.com/repos/calc/trunk\n\nIndex: integer.c\n===================================================================\n--- integer.c\t(revision 343)\n+++ integer.c\t(revision 344)\n@@ -147,7 +147,7 @@\n case 6: sprintf(info->operating_system, \"HPFS (OS/2 or NT)\"); break;\n case 7: sprintf(info->operating_system, \"Macintosh\"); break;\n case 8: sprintf(info->operating_system, \"Z-System\"); break;\n- case 9: sprintf(info->operating_system, \"CPM\"); break;\n+ case 9: sprintf(info->operating_system, \"CP/M\"); break;\n case 10: sprintf(info->operating_system, \"TOPS-20\"); break;\n case 11: sprintf(info->operating_system, \"NTFS (Windows NT)\"); break;\n case 12: sprintf(info->operating_system, \"QDOS\"); break;\n@@ -164,7 +164,7 @@\n low = (unsigned short) read_byte(gzfile); /* read LSB */\n high = (unsigned short) read_byte(gzfile); /* read MSB */\n high = high << 8; /* interpret MSB correctly */\n- total = low + high; /* add them togethe for correct total */\n+ total = low + high; /* add them together for correct total */\n\n info->extra_header = (unsigned char *) my_malloc(total);\n fread(info->extra_header, total, 1, gzfile);\n@@ -241,7 +241,7 @@\n Store the offset with ftell() ! */\n\n if ((info->data_offset = ftell(gzfile))== -1) {\n- printf(\"error: ftell() retturned -1.\\n\");\n+ printf(\"error: ftell() returned -1.\\n\");\n exit(1);\n }\n\n@@ -249,7 +249,7 @@\n printf(\"I believe start of compressed data is %u\\n\", info->data_offset);\n #endif\n\n- /* Set postion eight bytes from the end of the file. */\n+ /* Set position eight bytes from the end of the file. */\n\n if (fseek(gzfile, -8, SEEK_END)) {\n printf(\"error: fseek() returned non-zero\\n\");\n"
5205 #: ../source/book.xml:7152
5206 msgid "The <command>svn merge</command> command is almost exactly the same. Instead of printing the differences to your terminal, however, it applies them directly to your working copy as <emphasis>local modifications</emphasis>:"
5210 #: ../source/book.xml:7156
5212 msgid "\n$ svn merge -c 344 http://svn.example.com/repos/calc/trunk\nU integer.c\n\n$ svn status\nM integer.c\n"
5216 #: ../source/book.xml:7163
5217 msgid "The output of <command>svn merge</command> shows that your copy of <filename>integer.c</filename> was patched. It now contains Sally's change—the change has been <quote>copied</quote> from the trunk to your working copy of your private branch, and now exists as a local modification. At this point, it's up to you to review the local modification and make sure it works correctly."
5221 #: ../source/book.xml:7170
5222 msgid "In another scenario, it's possible that things may not have gone so well, and that <filename>integer.c</filename> may have entered a conflicted state. You might need to resolve the conflict using standard procedures (see <xref linkend=\"svn.tour\"/>), or if you decide that the merge was a bad idea altogether, simply give up and <command>svn revert</command> the local change."
5226 #: ../source/book.xml:7176
5227 msgid "But assuming that you've reviewed the merged change, you can <command>svn commit</command> the change as usual. At that point, the change has been merged into your repository branch. In version control terminology, this act of copying changes between branches is commonly called <firstterm>porting</firstterm> changes."
5231 #: ../source/book.xml:7182
5232 msgid "When you commit the local modification, make sure your log message mentions that you're porting a specific change from one branch to another. For example:"
5236 #: ../source/book.xml:7185
5238 msgid "\n$ svn commit -m \"integer.c: ported r344 (spelling fixes) from trunk.\"\nSending integer.c\nTransmitting file data .\nCommitted revision 360.\n"
5242 #: ../source/book.xml:7191
5243 msgid "As you'll see in the next sections, this is a very important <quote>best practice</quote> to follow."
5247 #: ../source/book.xml:7195
5248 msgid "Why Not Use Patches Instead?"
5252 #: ../source/book.xml:7197
5253 msgid "A question may be on your mind, especially if you're a Unix user: why bother to use <command>svn merge</command> at all? Why not simply use the operating system's <command>patch</command> command to accomplish the same job? For example:"
5257 #: ../source/book.xml:7202
5259 msgid "\n$ svn diff -c 344 http://svn.example.com/repos/calc/trunk > patchfile\n$ patch -p0 < patchfile\nPatching file integer.c using Plan A...\nHunk #1 succeeded at 147.\nHunk #2 succeeded at 164.\nHunk #3 succeeded at 241.\nHunk #4 succeeded at 249.\ndone\n"
5263 #: ../source/book.xml:7212
5264 msgid "In this particular case, yes, there really is no difference. But <command>svn merge</command> has special abilities that surpass the <command>patch</command> program. The file format used by <command>patch</command> is quite limited; it's only able to tweak file contents. There's no way to represent changes to <emphasis>trees</emphasis>, such as the addition, removal, or renaming of files and directories. Nor can the <command>patch</command> program notice changes to properties. If Sally's change had, say, added a new directory, the output of <command>svn diff</command> wouldn't have mentioned it at all. <command>svn diff</command> only outputs the limited patch-format, so there are some ideas it simply can't express. The <command>svn merge</command> command, however, can express changes in tree structure and properties by directly applying them to your working copy."
5268 #: ../source/book.xml:7229
5269 msgid "A word of warning: while <command>svn diff</command> and <command>svn merge</command> are very similar in concept, they do have different syntax in many cases. Be sure to read about them in <xref linkend=\"svn.ref\"/> for details, or ask <command>svn help</command>. For example, <command>svn merge</command> requires a working-copy path as a target, i.e. a place where it should apply the tree-changes. If the target isn't specified, it assumes you are trying to perform one of the following common operations:"
5273 #: ../source/book.xml:7240
5274 msgid "You want to merge directory changes into your current working directory."
5278 #: ../source/book.xml:7244
5279 msgid "You want to merge the changes in a specific file into a file by the same name which exists in your current working directory."
5283 #: ../source/book.xml:7249
5284 msgid "If you are merging a directory and haven't specified a target path, <command>svn merge</command> assumes the first case above and tries to apply the changes into your current directory. If you are merging a file, and that file (or a file by the same name) exists in your current working directory, <command>svn merge</command> assumes the second case and tries to apply the changes to a local file with the same name."
5288 #: ../source/book.xml:7256
5289 msgid "If you want changes applied somewhere else, you'll need to say so. For example, if you're sitting in the parent directory of your working copy, you'll have to specify the target directory to receive the changes:"
5293 #: ../source/book.xml:7260
5295 msgid "\n$ svn merge -c 344 http://svn.example.com/repos/calc/trunk my-calc-branch\nU my-calc-branch/integer.c\n"
5299 #: ../source/book.xml:7268
5300 msgid "The Key Concept Behind Merging"
5304 #: ../source/book.xml:7270
5305 msgid "You've now seen an example of the <command>svn merge</command> command, and you're about to see several more. If you're feeling confused about exactly how merging works, you're not alone. Many users (especially those new to version control) are initially perplexed about the proper syntax of the command, and about how and when the feature should be used. But fear not, this command is actually much simpler than you think! There's a very easy technique for understanding exactly how <command>svn merge</command> behaves."
5309 #: ../source/book.xml:7280
5310 msgid "The main source of confusion is the <emphasis>name</emphasis> of the command. The term <quote>merge</quote> somehow denotes that branches are combined together, or that there's some sort of mysterious blending of data going on. That's not the case. A better name for the command might have been <command>svn diff-and-apply</command>, because that's all that happens: two repository trees are compared, and the differences are applied to a working copy."
5314 #: ../source/book.xml:7289
5315 msgid "The command takes three arguments:"
5319 #: ../source/book.xml:7292
5320 msgid "An initial repository tree (often called the <firstterm>left side</firstterm> of the comparison),"
5324 #: ../source/book.xml:7297
5325 msgid "A final repository tree (often called the <firstterm>right side</firstterm> of the comparison),"
5329 #: ../source/book.xml:7302
5330 msgid "A working copy to accept the differences as local changes (often called the <firstterm>target</firstterm> of the merge)."
5334 #: ../source/book.xml:7307
5335 msgid "Once these three arguments are specified, the two trees are compared, and the resulting differences are applied to the target working copy as local modifications. When the command is done, the results are no different than if you had hand-edited the files, or run various <command>svn add</command> or <command>svn delete</command> commands yourself. If you like the results, you can commit them. If you don't like the results, you can simply <command>svn revert</command> all of the changes."
5339 #: ../source/book.xml:7316
5340 msgid "The syntax of <command>svn merge</command> allows you to specify the three necessary arguments rather flexibly. Here are some examples:"
5344 #: ../source/book.xml:7319
5346 msgid "\n$ svn merge http://svn.example.com/repos/branch1@150 \\\n http://svn.example.com/repos/branch2@212 \\\n my-working-copy\n\n$ svn merge -r 100:200 http://svn.example.com/repos/trunk my-working-copy\n\n$ svn merge -r 100:200 http://svn.example.com/repos/trunk\n"
5350 #: ../source/book.xml:7328
5351 msgid "The first syntax lays out all three arguments explicitly, naming each tree in the form <emphasis>URL@REV</emphasis> and naming the working copy target. The second syntax can be used as a shorthand for situations when you're comparing two different revisions of the same URL. The last syntax shows how the working-copy argument is optional; if omitted, it defaults to the current directory."
5355 #: ../source/book.xml:7339
5356 msgid "Best Practices for Merging"
5360 #: ../source/book.xml:7344
5361 msgid "Tracking Merges Manually"
5365 #: ../source/book.xml:7346
5366 msgid "Merging changes sounds simple enough, but in practice it can become a headache. The problem is that if you repeatedly merge changes from one branch to another, you might accidentally merge the same change <emphasis>twice</emphasis>. When this happens, sometimes things will work fine. When patching a file, Subversion typically notices if the file already has the change, and does nothing. But if the already-existing change has been modified in any way, you'll get a conflict."
5370 #: ../source/book.xml:7355
5371 msgid "Ideally, your version control system should prevent the double-application of changes to a branch. It should automatically remember which changes a branch has already received, and be able to list them for you. It should use this information to help automate merges as much as possible."
5375 #: ../source/book.xml:7363
5376 msgid "However, at the time of writing, this feature is being worked on!"
5380 #: ../source/book.xml:7361
5381 msgid "Unfortunately, Subversion is not such a system; it does not yet record any information about merge operations. <placeholder-1/> When you commit local modifications, the repository has no idea whether those changes came from running <command>svn merge</command>, or from just hand-editing the files."
5385 #: ../source/book.xml:7368
5386 msgid "What does this mean to you, the user? It means that until the day Subversion grows this feature, you'll have to track merge information yourself. The best place to do this is in the commit log-message. As demonstrated in prior examples, it's recommended that your log-message mention a specific revision number (or range of revisions) that are being merged into your branch. Later on, you can run <command>svn log</command> to review which changes your branch already contains. This will allow you to carefully construct a subsequent <command>svn merge</command> command that won't be redundant with previously ported changes."
5390 #: ../source/book.xml:7380
5391 msgid "In the next section, we'll show some examples of this technique in action."
5395 #: ../source/book.xml:7386
5396 msgid "Previewing Merges"
5400 #: ../source/book.xml:7388
5401 msgid "First, always remember to do your merge into a working copy that has <emphasis>no</emphasis> local edits and has been recently updated. If your working copy isn't <quote>clean</quote> in these ways, you can run into some headaches."
5405 #: ../source/book.xml:7393
5406 msgid "Assuming your working copy is tidy, merging isn't a particularly high-risk operation. If you get the merge wrong the first time, simply <command>svn revert</command> the changes and try again."
5410 #: ../source/book.xml:7397
5411 msgid "If you've merged into a working copy that already has local modifications, the changes applied by a merge will be mixed with your pre-existing ones, and running <command>svn revert</command> is no longer an option. The two sets of changes may be impossible to separate."
5415 #: ../source/book.xml:7402
5416 msgid "In cases like this, people take comfort in being able to predict or examine merges before they happen. One simple way to do that is to run <command>svn diff</command> with the same arguments you plan to pass to <command>svn merge</command>, as we already showed in our first example of merging. Another method of previewing is to pass the <option>--dry-run</option> option to the merge command:"
5420 #: ../source/book.xml:7410
5422 msgid "\n$ svn merge --dry-run -c 344 http://svn.example.com/repos/calc/trunk\nU integer.c\n\n$ svn status\n# nothing printed, working copy is still unchanged.\n"
5426 #: ../source/book.xml:7417
5427 msgid "The <option>--dry-run</option> option doesn't actually apply any local changes to the working copy. It only shows status codes that <emphasis>would</emphasis> be printed in a real merge. It's useful for getting a <quote>high level</quote> preview of the potential merge, for those times when running <command>svn diff</command> gives too much detail."
5431 #: ../source/book.xml:7428
5432 msgid "Merge Conflicts"
5436 #: ../source/book.xml:7430
5437 msgid "Just like the <command>svn update</command> command, <command>svn merge</command> applies changes to your working copy. And therefore it's also capable of creating conflicts. The conflicts produced by <command>svn merge</command>, however, are sometimes different, and this section explains those differences."
5441 #: ../source/book.xml:7436
5442 msgid "To begin with, assume that your working copy has no local edits. When you <command>svn update</command> to a particular revision, the changes sent by the server will always apply <quote>cleanly</quote> to your working copy. The server produces the delta by comparing two trees: a virtual snapshot of your working copy, and the revision tree you're interested in. Because the left-hand side of the comparison is exactly equal to what you already have, the delta is guaranteed to correctly convert your working copy into the right-hand tree."
5446 #: ../source/book.xml:7446
5447 msgid "But <command>svn merge</command> has no such guarantees and can be much more chaotic: the user can ask the server to compare <emphasis>any</emphasis> two trees at all, even ones that are unrelated to the working copy! This means there's large potential for human error. Users will sometimes compare the wrong two trees, creating a delta that doesn't apply cleanly. <command>svn merge</command> will do its best to apply as much of the delta as possible, but some parts may be impossible. Just as the Unix <command>patch</command> command sometimes complains about <quote>failed hunks</quote>, <command>svn merge</command> will complain about <quote>skipped targets</quote>:"
5451 #: ../source/book.xml:7458
5453 msgid "\n$ svn merge -r 1288:1351 http://svn.example.com/repos/branch\nU foo.c\nU bar.c\nSkipped missing target: 'baz.c'\nU glub.c\nC glorb.h\n\n$\n"
5457 #: ../source/book.xml:7468
5458 msgid "In the previous example it might be the case that <filename>baz.c</filename> exists in both snapshots of the branch being compared, and the resulting delta wants to change the file's contents, but the file doesn't exist in the working copy. Whatever the case, the <quote>skipped</quote> message means that the user is most likely comparing the wrong two trees; they're the classic sign of user error. When this happens, it's easy to recursively revert all the changes created by the merge (<command>svn revert --recursive</command>), delete any unversioned files or directories left behind after the revert, and re-run <command>svn merge</command> with different arguments."
5462 #: ../source/book.xml:7481
5463 msgid "Also notice that the previous example shows a conflict happening on <filename>glorb.h</filename>. We already stated that the working copy has no local edits: how can a conflict possibly happen? Again, because the user can use <command>svn merge</command> to define and apply any old delta to the working copy, that delta may contain textual changes that don't cleanly apply to a working file, even if the file has no local modifications."
5467 #: ../source/book.xml:7489
5468 msgid "Another small difference between <command>svn update</command> and <command>svn merge</command> are the names of the full-text files created when a conflict happens. In <xref linkend=\"svn.tour.cycle.resolve\"/>, we saw that an update produces files named <filename>filename.mine</filename>, <filename>filename.rOLDREV</filename>, and <filename>filename.rNEWREV</filename>. When <command>svn merge</command> produces a conflict, though, it creates three files named <filename>filename.working</filename>, <filename>filename.left</filename>, and <filename>filename.right</filename>. In this case, the terms <quote>left</quote> and <quote>right</quote> are describing which side of the double-tree comparison the file came from. In any case, these differing names will help you distinguish between conflicts that happened as a result of an update versus ones that happened as a result of a merge."
5472 #: ../source/book.xml:7511
5473 msgid "Noticing or Ignoring Ancestry"
5477 #: ../source/book.xml:7513
5478 msgid "When conversing with a Subversion developer, you might very likely hear reference to the term <firstterm>ancestry</firstterm>. This word is used to describe the relationship between two objects in a repository: if they're related to each other, then one object is said to be an ancestor of the other."
5482 #: ../source/book.xml:7519
5483 msgid "For example, suppose you commit revision 100, which includes a change to a file <filename>foo.c</filename>. Then <filename>foo.c@99</filename> is an <quote>ancestor</quote> of <filename>foo.c@100</filename>. On the other hand, suppose you commit the deletion of <filename>foo.c</filename> in revision 101, and then add a new file by the same name in revision 102. In this case, <filename>foo.c@99</filename> and <filename>foo.c@102</filename> may appear to be related (they have the same path), but in fact are completely different objects in the repository. They share no history or <quote>ancestry</quote>."
5487 #: ../source/book.xml:7531
5488 msgid "The reason for bringing this up is to point out an important difference between <command>svn diff</command> and <command>svn merge</command>. The former command ignores ancestry, while the latter command is quite sensitive to it. For example, if you asked <command>svn diff</command> to compare revisions 99 and 102 of <filename>foo.c</filename>, you would see line-based diffs; the <literal>diff</literal> command is blindly comparing two paths. But if you asked <command>svn merge</command> to compare the same two objects, it would notice that they're unrelated and first attempt to delete the old file, then add the new file; the output would indicate a deletion followed by an add:"
5492 #: ../source/book.xml:7543
5494 msgid "\nD foo.c\nA foo.c\n"
5498 #: ../source/book.xml:7547
5499 msgid "Most merges involve comparing trees that are ancestrally related to one another, and therefore <command>svn merge</command> defaults to this behavior. Occasionally, however, you may want the <literal>merge</literal> command to compare two unrelated trees. For example, you may have imported two source-code trees representing different vendor releases of a software project (see <xref linkend=\"svn.advanced.vendorbr\"/>). If you asked <command>svn merge</command> to compare the two trees, you'd see the entire first tree being deleted, followed by an add of the entire second tree! In these situations, you'll want <command>svn merge</command> to do a path-based comparison only, ignoring any relations between files and directories. Add the <option>--ignore-ancestry</option> option to your merge command, and it will behave just like <command>svn diff</command>. (And conversely, the <option>--notice-ancestry</option> option will cause <command>svn diff</command> to behave like the <literal>merge</literal> command.)"
5503 #: ../source/book.xml:7569
5504 msgid "Merges and Moves"
5508 #: ../source/book.xml:7571
5509 msgid "A common desire is to refactor source code, especially in Java-based software projects. Files and directories are shuffled around and renamed, often causing great disruption to everyone working on the project. Sounds like a perfect case to use a branch, doesn't it? Just create a branch, shuffle things around, then merge the branch back to the trunk, right?"
5513 #: ../source/book.xml:7578
5514 msgid "Alas, this scenario doesn't work so well right now, and is considered one of Subversion's current weak spots. The problem is that Subversion's <command>update</command> command isn't as robust as it should be, particularly when dealing with copy and move operations."
5518 #: ../source/book.xml:7583
5519 msgid "When you use <command>svn copy</command> to duplicate a file, the repository remembers where the new file came from, but it fails to transmit that information to the client which is running <command>svn update</command> or <command>svn merge</command>. Instead of telling the client, <quote>Copy that file you already have to this new location</quote>, it instead sends down an entirely new file. This can lead to problems, especially because the same thing happens with renamed files. A lesser-known fact about Subversion is that it lacks <quote>true renames</quote>—the <command>svn move</command> command is nothing more than an aggregation of <command>svn copy</command> and <command>svn delete</command>."
5523 #: ../source/book.xml:7596
5524 msgid "For example, suppose that while working on your private branch, you rename <filename>integer.c</filename> to <filename>whole.c</filename>. Effectively you've created a new file in your branch that is a copy of the original file, and deleted the original file. Meanwhile, back on <filename>trunk</filename>, Sally has committed some improvements to <filename>integer.c</filename>. Now you decide to merge your branch to the trunk:"
5528 #: ../source/book.xml:7604
5530 msgid "\n$ cd calc/trunk\n\n$ svn merge -r 341:405 http://svn.example.com/repos/calc/branches/my-calc-branch\nD integer.c\nA whole.c\n"
5534 #: ../source/book.xml:7611
5535 msgid "This doesn't look so bad at first glance, but it's also probably not what you or Sally expected. The merge operation has deleted the latest version of <filename>integer.c</filename> file (the one containing Sally's latest changes), and blindly added your new <filename>whole.c</filename> file—which is a duplicate of the <emphasis>older</emphasis> version of <filename>integer.c</filename>. The net effect is that merging your <quote>rename</quote> to the branch has removed Sally's recent changes from the latest revision!"
5539 #: ../source/book.xml:7621
5540 msgid "This isn't true data-loss; Sally's changes are still in the repository's history, but it may not be immediately obvious that this has happened. The moral of this story is that until Subversion improves, be very careful about merging copies and renames from one branch to another."
5544 #: ../source/book.xml:7635
5545 msgid "Common Use-Cases"
5549 #: ../source/book.xml:7637
5550 msgid "There are many different uses for branching and <command>svn merge</command>, and this section describes the most common ones you're likely to run into."
5554 #: ../source/book.xml:7643
5555 msgid "Merging a Whole Branch to Another"
5559 #: ../source/book.xml:7645
5560 msgid "To complete our running example, we'll move forward in time. Suppose several days have passed, and many changes have happened on both the trunk and your private branch. Suppose that you've finished working on your private branch; the feature or bug fix is finally complete, and now you want to merge all of your branch changes back into the trunk for others to enjoy."
5564 #: ../source/book.xml:7652
5565 msgid "So how do we use <command>svn merge</command> in this scenario? Remember that this command compares two trees, and applies the differences to a working copy. So to receive the changes, you need to have a working copy of the trunk. We'll assume that either you still have your original one lying around (fully updated), or that you recently checked out a fresh working copy of <filename>/calc/trunk</filename>."
5569 #: ../source/book.xml:7659
5570 msgid "But which two trees should be compared? At first glance, the answer may seem obvious: just compare the latest trunk tree with your latest branch tree. But beware—this assumption is <emphasis>wrong</emphasis>, and has burned many a new user! Since <command>svn merge</command> operates like <command>svn diff</command>, comparing the latest trunk and branch trees will <emphasis>not</emphasis> merely describe the set of changes you made to your branch. Such a comparison shows too many changes: it would not only show the addition of your branch changes, but also the <emphasis>removal</emphasis> of trunk changes that never happened on your branch."
5574 #: ../source/book.xml:7670
5575 msgid "To express only the changes that happened on your branch, you need to compare the initial state of your branch to its final state. Using <command>svn log</command> on your branch, you can see that your branch was created in revision 341. And the final state of your branch is simply a matter of using the <literal>HEAD</literal> revision. That means you want to compare revisions 341 and <literal>HEAD</literal> of your branch directory, and apply those differences to a working copy of the trunk."
5579 #: ../source/book.xml:7680
5580 msgid "A nice way of finding the revision in which a branch was created (the <quote>base</quote> of the branch) is to use the <option>--stop-on-copy</option> option to <command>svn log</command>. The log subcommand will normally show every change ever made to the branch, including tracing back through the copy which created the branch. So normally, you'll see history from the trunk as well. The <option>--stop-on-copy</option> will halt log output as soon as <command>svn log</command> detects that its target was copied or renamed."
5584 #: ../source/book.xml:7690
5585 msgid "So in our continuing example,"
5589 #: ../source/book.xml:7691
5591 msgid "\n$ svn log -v --stop-on-copy \\\n http://svn.example.com/repos/calc/branches/my-calc-branch\n…\n------------------------------------------------------------------------\nr341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines\nChanged paths:\n A /calc/branches/my-calc-branch (from /calc/trunk:340)\n\n$\n"
5595 #: ../source/book.xml:7702
5596 msgid "As expected, the final revision printed by this command is the revision in which <filename>my-calc-branch</filename> was created by copying."
5600 #: ../source/book.xml:7706
5601 msgid "Here's the final merging procedure, then:"
5605 #: ../source/book.xml:7707
5607 msgid "\n$ cd calc/trunk\n$ svn update\nAt revision 405.\n\n$ svn merge -r 341:405 http://svn.example.com/repos/calc/branches/my-calc-branch\nU integer.c\nU button.c\nU Makefile\n\n$ svn status\nM integer.c\nM button.c\nM Makefile\n\n# ...examine the diffs, compile, test, etc...\n\n$ svn commit -m \"Merged my-calc-branch changes r341:405 into the trunk.\"\nSending integer.c\nSending button.c\nSending Makefile\nTransmitting file data ...\nCommitted revision 406.\n"
5611 #: ../source/book.xml:7731
5612 msgid "Again, notice that the commit log message very specifically mentions the range of changes that was merged into the trunk. Always remember to do this, because it's critical information you'll need later on."
5616 #: ../source/book.xml:7735
5617 msgid "For example, suppose you decide to keep working on your branch for another week, in order to complete an enhancement to your original feature or bug fix. The repository's <literal>HEAD</literal> revision is now 480, and you're ready to do another merge from your private branch to the trunk. But as discussed in <xref linkend=\"svn.branchmerge.copychanges.bestprac\"/>, you don't want to merge the changes you've already merged before; you only want to merge everything <quote>new</quote> on your branch since the last time you merged. The trick is to figure out what's new."
5621 #: ../source/book.xml:7745
5622 msgid "The first step is to run <command>svn log</command> on the trunk, and look for a log message about the last time you merged from the branch:"
5626 #: ../source/book.xml:7748
5628 msgid "\n$ cd calc/trunk\n$ svn log\n…\n------------------------------------------------------------------------\nr406 | user | 2004-02-08 11:17:26 -0600 (Sun, 08 Feb 2004) | 1 line\n\nMerged my-calc-branch changes r341:405 into the trunk.\n------------------------------------------------------------------------\n…\n"
5632 #: ../source/book.xml:7759
5633 msgid "Aha! Since all branch-changes that happened between revisions 341 and 405 were previously merged to the trunk as revision 406, you now know that you want to merge only the branch changes after that—by comparing revisions 406 and <literal>HEAD</literal>."
5637 #: ../source/book.xml:7764
5639 msgid "\n$ cd calc/trunk\n$ svn update\nAt revision 480.\n\n# We notice that HEAD is currently 480, so we use it to do the merge:\n\n$ svn merge -r 406:480 http://svn.example.com/repos/calc/branches/my-calc-branch\nU integer.c\nU button.c\nU Makefile\n\n$ svn commit -m \"Merged my-calc-branch changes r406:480 into the trunk.\"\nSending integer.c\nSending button.c\nSending Makefile\nTransmitting file data ...\nCommitted revision 481.\n"
5643 #: ../source/book.xml:7783
5644 msgid "Now the trunk contains the complete second wave of changes made to the branch. At this point, you can either delete your branch (we'll discuss this later on), or continue working on your branch and repeat this procedure for subsequent merges."
5648 #: ../source/book.xml:7792
5649 msgid "Undoing Changes"
5653 #: ../source/book.xml:7794
5654 msgid "Another common use for <command>svn merge</command> is to roll back a change that has already been committed. Suppose you're working away happily on a working copy of <filename>/calc/trunk</filename>, and you discover that the change made way back in revision 303, which changed <filename>integer.c</filename>, is completely wrong. It never should have been committed. You can use <command>svn merge</command> to <quote>undo</quote> the change in your working copy, and then commit the local modification to the repository. All you need to do is to specify a <emphasis>reverse</emphasis> difference. (You can do this by specifying <option>--revision 303:302</option>, or by an equivalent <option>--change -303</option>.)"
5658 #: ../source/book.xml:7807
5660 msgid "\n$ svn merge -c -303 http://svn.example.com/repos/calc/trunk\nU integer.c\n\n$ svn status\nM integer.c\n\n$ svn diff\n…\n# verify that the change is removed\n…\n\n$ svn commit -m \"Undoing change committed in r303.\"\nSending integer.c\nTransmitting file data .\nCommitted revision 350.\n"
5664 #: ../source/book.xml:7824
5665 msgid "One way to think about a repository revision is as a specific group of changes (some version control systems call these <firstterm>changesets</firstterm>). By using the <option>-r</option> option, you can ask <command>svn merge</command> to apply a changeset, or whole range of changesets, to your working copy. In our case of undoing a change, we're asking <command>svn merge</command> to apply changeset #303 to our working copy <emphasis>backwards</emphasis>."
5669 #: ../source/book.xml:7835
5670 msgid "Subversion and Changesets"
5674 #: ../source/book.xml:7837
5675 msgid "Everyone seems to have a slightly different definition of <quote>changeset</quote>, or at least a different expectation of what it means for a version control system to have <quote>changeset features</quote>. For our purpose, let's say that a changeset is just a collection of changes with a unique name. The changes might include textual edits to file contents, modifications to tree structure, or tweaks to metadata. In more common speak, a changeset is just a patch with a name you can refer to."
5679 #: ../source/book.xml:7846
5680 msgid "In Subversion, a global revision number N names a tree in the repository: it's the way the repository looked after the Nth commit. It's also the name of an implicit changeset: if you compare tree N with tree N-1, you can derive the exact patch that was committed. For this reason, it's easy to think of <quote>revision N</quote> as not just a tree, but a changeset as well. If you use an issue tracker to manage bugs, you can use the revision numbers to refer to particular patches that fix bugs—for example, <quote>this issue was fixed by revision 9238.</quote>. Somebody can then run <command>svn log -r9238</command> to read about the exact changeset which fixed the bug, and run <command>svn diff -c 9238</command> to see the patch itself. And Subversion's <literal>merge</literal> command also uses revision numbers. You can merge specific changesets from one branch to another by naming them in the merge arguments: <command>svn merge -r9237:9238</command> would merge changeset #9238 into your working copy."
5684 #: ../source/book.xml:7865
5685 msgid "Keep in mind that rolling back a change like this is just like any other <command>svn merge</command> operation, so you should use <command>svn status</command> and <command>svn diff</command> to confirm that your work is in the state you want it to be in, and then use <command>svn commit</command> to send the final version to the repository. After committing, this particular changeset is no longer reflected in the <literal>HEAD</literal> revision."
5689 #: ../source/book.xml:7873
5690 msgid "Again, you may be thinking: well, that really didn't undo the commit, did it? The change still exists in revision 303. If somebody checks out a version of the <filename>calc</filename> project between revisions 303 and 349, they'll still see the bad change, right?"
5694 #: ../source/book.xml:7893
5695 msgid "The Subversion project has plans, however, to someday implement a command that would accomplish the task of permanently deleting information. In the meantime, see <xref linkend=\"svn.reposadmin.maint.tk.svndumpfilter\"/> for a possible workaround."
5699 #: ../source/book.xml:7878
5700 msgid "Yes, that's true. When we talk about <quote>removing</quote> a change, we're really talking about removing it from <literal>HEAD</literal>. The original change still exists in the repository's history. For most situations, this is good enough. Most people are only interested in tracking the <literal>HEAD</literal> of a project anyway. There are special cases, however, where you really might want to destroy all evidence of the commit. (Perhaps somebody accidentally committed a confidential document.) This isn't so easy, it turns out, because Subversion was deliberately designed to never lose information. Revisions are immutable trees which build upon one another. Removing a revision from history would cause a domino effect, creating chaos in all subsequent revisions and possibly invalidating all working copies. <placeholder-1/>"
5704 #: ../source/book.xml:7903
5705 msgid "Resurrecting Deleted Items"
5709 #: ../source/book.xml:7905
5710 msgid "The great thing about version control systems is that information is never lost. Even when you delete a file or directory, it may be gone from the <literal>HEAD</literal> revision, but the object still exists in earlier revisions. One of the most common questions new users ask is, <quote>How do I get my old file or directory back?</quote>."
5714 #: ../source/book.xml:7911
5715 msgid "The first step is to define exactly <emphasis role=\"bold\">which</emphasis> item you're trying to resurrect. Here's a useful metaphor: you can think of every object in the repository as existing in a sort of two-dimensional coordinate system. The first coordinate is a particular revision tree, and the second coordinate is a path within that tree. So every version of your file or directory can be defined by a specific coordinate pair. (Remember the <quote>peg revision</quote> syntax—foo.c@224 —mentioned back in <xref linkend=\"svn.advanced.pegrevs\"/>.)"
5719 #: ../source/book.xml:7922
5720 msgid "First, you might need to use <command>svn log</command> to discover the exact coordinate pair you wish to resurrect. A good strategy is to run <command>svn log --verbose</command> in a directory which used to contain your deleted item. The <option>--verbose (-v)</option> option shows a list of all changed items in each revision; all you need to do is find the revision in which you deleted the file or directory. You can do this visually, or by using another tool to examine the log output (via <command>grep</command>, or perhaps via an incremental search in an editor)."
5724 #: ../source/book.xml:7932
5726 msgid "\n$ cd parent-dir\n$ svn log -v\n…\n------------------------------------------------------------------------\nr808 | joe | 2003-12-26 14:29:40 -0600 (Fri, 26 Dec 2003) | 3 lines\nChanged paths:\n D /calc/trunk/real.c\n M /calc/trunk/integer.c\n\nAdded fast fourier transform functions to integer.c.\nRemoved real.c because code now in double.c.\n…\n"
5730 #: ../source/book.xml:7946
5731 msgid "In the example, we're assuming that you're looking for a deleted file <filename>real.c</filename>. By looking through the logs of a parent directory, you've spotted that this file was deleted in revision 808. Therefore, the last version of the file to exist was in the revision right before that. Conclusion: you want to resurrect the path <filename>/calc/trunk/real.c</filename> from revision 807."
5735 #: ../source/book.xml:7954
5736 msgid "That was the hard part—the research. Now that you know what you want to restore, you have two different choices."
5740 #: ../source/book.xml:7957
5741 msgid "One option is to use <command>svn merge</command> to apply revision 808 <quote>in reverse</quote>. (We've already discussed how to undo changes, see <xref linkend=\"svn.branchmerge.commonuses.undo\"/>.) This would have the effect of re-adding <filename>real.c</filename> as a local modification. The file would be scheduled for addition, and after a commit, the file would again exist in <literal>HEAD</literal>."
5745 #: ../source/book.xml:7965
5746 msgid "In this particular example, however, this is probably not the best strategy. Reverse-applying revision 808 would not only schedule <filename>real.c</filename> for addition, but the log message indicates that it would also undo certain changes to <filename>integer.c</filename>, which you don't want. Certainly, you could reverse-merge revision 808 and then <command>svn revert</command> the local modifications to <filename>integer.c</filename>, but this technique doesn't scale well. What if there were 90 files changed in revision 808?"
5750 #: ../source/book.xml:7975
5751 msgid "A second, more targeted strategy is not to use <command>svn merge</command> at all, but rather the <command>svn copy</command> command. Simply copy the exact revision and path <quote>coordinate pair</quote> from the repository to your working copy:"
5755 #: ../source/book.xml:7980
5757 msgid "\n$ svn copy -r 807 \\\n http://svn.example.com/repos/calc/trunk/real.c ./real.c\n\n$ svn status\nA + real.c\n\n$ svn commit -m \"Resurrected real.c from revision 807, /calc/trunk/real.c.\"\nAdding real.c\nTransmitting file data .\nCommitted revision 1390.\n"
5761 #: ../source/book.xml:7992
5762 msgid "The plus sign in the status output indicates that the item isn't merely scheduled for addition, but scheduled for addition <quote>with history</quote>. Subversion remembers where it was copied from. In the future, running <command>svn log</command> on this file will traverse back through the file's resurrection and through all the history it had prior to revision 807. In other words, this new <filename>real.c</filename> isn't really new; it's a direct descendant of the original, deleted file."
5766 #: ../source/book.xml:8001
5767 msgid "Although our example shows us resurrecting a file, note that these same techniques work just as well for resurrecting deleted directories."
5771 #: ../source/book.xml:8008
5772 msgid "Common Branching Patterns"
5776 #: ../source/book.xml:8010
5777 msgid "Version control is most often used for software development, so here's a quick peek at two of the most common branching/merging patterns used by teams of programmers. If you're not using Subversion for software development, feel free to skip this section. If you're a software developer using version control for the first time, pay close attention, as these patterns are often considered best practices by experienced folk. These processes aren't specific to Subversion; they're applicable to any version control system. Still, it may help to see them described in Subversion terms."
5781 #: ../source/book.xml:8024
5782 msgid "Release Branches"
5786 #: ../source/book.xml:8026
5787 msgid "Most software has a typical lifecycle: code, test, release, repeat. There are two problems with this process. First, developers need to keep writing new features while quality-assurance teams take time to test supposedly-stable versions of the software. New work cannot halt while the software is tested. Second, the team almost always needs to support older, released versions of software; if a bug is discovered in the latest code, it most likely exists in released versions as well, and customers will want to get that bugfix without having to wait for a major new release."
5791 #: ../source/book.xml:8037
5792 msgid "Here's where version control can help. The typical procedure looks like this:"
5796 #: ../source/book.xml:8041
5797 msgid "<emphasis>Developers commit all new work to the trunk.</emphasis> Day-to-day changes are committed to <filename>/trunk</filename>: new features, bugfixes, and so on."
5801 #: ../source/book.xml:8049
5802 msgid "<emphasis>The trunk is copied to a <quote>release</quote> branch.</emphasis> When the team thinks the software is ready for release (say, a 1.0 release), then <filename>/trunk</filename> might be copied to <filename>/branches/1.0</filename>."
5806 #: ../source/book.xml:8058
5807 msgid "<emphasis>Teams continue to work in parallel.</emphasis> One team begins rigorous testing of the release branch, while another team continues new work (say, for version 2.0) on <filename>/trunk</filename>. If bugs are discovered in either location, fixes are ported back and forth as necessary. At some point, however, even that process stops. The branch is <quote>frozen</quote> for final testing right before a release."
5811 #: ../source/book.xml:8069
5812 msgid "<emphasis>The branch is tagged and released.</emphasis> When testing is complete, <filename>/branches/1.0</filename> is copied to <filename>/tags/1.0.0</filename> as a reference snapshot. The tag is packaged and released to customers."
5816 #: ../source/book.xml:8078
5817 msgid "<emphasis>The branch is maintained over time.</emphasis> While work continues on <filename>/trunk</filename> for version 2.0, bugfixes continue to be ported from <filename>/trunk</filename> to <filename>/branches/1.0</filename>. When enough bugfixes have accumulated, management may decide to do a 1.0.1 release: <filename>/branches/1.0</filename> is copied to <filename>/tags/1.0.1</filename>, and the tag is packaged and released."
5821 #: ../source/book.xml:8090
5822 msgid "This entire process repeats as the software matures: when the 2.0 work is complete, a new 2.0 release branch is created, tested, tagged, and eventually released. After some years, the repository ends up with a number of release branches in <quote>maintenance</quote> mode, and a number of tags representing final shipped versions."
5826 #: ../source/book.xml:8100
5827 msgid "Feature Branches"
5831 #: ../source/book.xml:8102
5832 msgid "A <firstterm>feature branch</firstterm> is the sort of branch that's been the dominant example in this chapter, the one you've been working on while Sally continues to work on <filename>/trunk</filename>. It's a temporary branch created to work on a complex change without interfering with the stability of <filename>/trunk</filename>. Unlike release branches (which may need to be supported forever), feature branches are born, used for a while, merged back to the trunk, then ultimately deleted. They have a finite span of usefulness."
5836 #: ../source/book.xml:8112
5837 msgid "Again, project policies vary widely concerning exactly when it's appropriate to create a feature branch. Some projects never use feature branches at all: commits to <filename>/trunk</filename> are a free-for-all. The advantage to this system is that it's simple—nobody needs to learn about branching or merging. The disadvantage is that the trunk code is often unstable or unusable. Other projects use branches to an extreme: no change is <emphasis>ever</emphasis> committed to the trunk directly. Even the most trivial changes are created on a short-lived branch, carefully reviewed and merged to the trunk. Then the branch is deleted. This system guarantees an exceptionally stable and usable trunk at all times, but at the cost of tremendous process overhead."
5841 #: ../source/book.xml:8126
5842 msgid "Most projects take a middle-of-the-road approach. They commonly insist that <filename>/trunk</filename> compile and pass regression tests at all times. A feature branch is only required when a change requires a large number of destabilizing commits. A good rule of thumb is to ask this question: if the developer worked for days in isolation and then committed the large change all at once (so that <filename>/trunk</filename> were never destabilized), would it be too large a change to review? If the answer to that question is <quote>yes</quote>, then the change should be developed on a feature branch. As the developer commits incremental changes to the branch, they can be easily reviewed by peers."
5846 #: ../source/book.xml:8139
5847 msgid "Finally, there's the issue of how to best keep a feature branch in <quote>sync</quote> with the trunk as work progresses. As we mentioned earlier, there's a great risk to working on a branch for weeks or months; trunk changes may continue to pour in, to the point where the two lines of development differ so greatly that it may become a nightmare trying to merge the branch back to the trunk."
5851 #: ../source/book.xml:8146
5852 msgid "This situation is best avoided by regularly merging trunk changes to the branch. Make up a policy: once a week, merge the last week's worth of trunk changes to the branch. Take care when doing this; the merging needs to be hand-tracked to avoid the problem of repeated merges (as described in <xref linkend=\"svn.branchmerge.copychanges.bestprac.track\"/>). You'll need to write careful log messages detailing exactly which revision ranges have been merged already (as demonstrated in <xref linkend=\"svn.branchmerge.commonuses.wholebr\"/>). It may sound intimidating, but it's actually pretty easy to do."
5856 #: ../source/book.xml:8159
5857 msgid "At some point, you'll be ready to merge the <quote>synchronized</quote> feature branch back to the trunk. To do this, begin by doing a final merge of the latest trunk changes to the branch. When that's done, the latest versions of branch and trunk will be absolutely identical except for your branch changes. So in this special case, you would merge by comparing the branch with the trunk:"
5861 #: ../source/book.xml:8167
5863 msgid "\n$ cd trunk-working-copy\n\n$ svn update\nAt revision 1910.\n\n$ svn merge http://svn.example.com/repos/calc/trunk@1910 \\\n http://svn.example.com/repos/calc/branches/mybranch@1910\nU real.c\nU integer.c\nA newdirectory\nA newdirectory/newfile\n…\n"
5867 #: ../source/book.xml:8181
5868 msgid "By comparing the <literal>HEAD</literal> revision of the trunk with the <literal>HEAD</literal> revision of the branch, you're defining a delta that describes only the changes you made to the branch; both lines of development already have all of the trunk changes."
5872 #: ../source/book.xml:8186
5873 msgid "Another way of thinking about this pattern is that your weekly sync of trunk to branch is analogous to running <command>svn update</command> in a working copy, while the final merge step is analogous to running <command>svn commit</command> from a working copy. After all, what else <emphasis>is</emphasis> a working copy but a very shallow private branch? It's a branch that's only capable of storing one change at a time."
5877 #: ../source/book.xml:8202
5878 msgid "Traversing Branches"
5882 #: ../source/book.xml:8204
5883 msgid "The <command>svn switch</command> command transforms an existing working copy to reflect a different branch. While this command isn't strictly necessary for working with branches, it provides a nice shortcut. In our earlier example, after creating your private branch, you checked out a fresh working copy of the new repository directory. Instead, you can simply ask Subversion to change your working copy of <filename>/calc/trunk</filename> to mirror the new branch location:"
5887 #: ../source/book.xml:8213
5889 msgid "\n$ cd calc\n\n$ svn info | grep URL\nURL: http://svn.example.com/repos/calc/trunk\n\n$ svn switch http://svn.example.com/repos/calc/branches/my-calc-branch\nU integer.c\nU button.c\nU Makefile\nUpdated to revision 341.\n\n$ svn info | grep URL\nURL: http://svn.example.com/repos/calc/branches/my-calc-branch\n"
5893 #: ../source/book.xml:8228
5894 msgid "After <quote>switching</quote> to the branch, your working copy is no different than what you would get from doing a fresh checkout of the directory. And it's usually more efficient to use this command, because often branches only differ by a small degree. The server sends only the minimal set of changes necessary to make your working copy reflect the branch directory."
5898 #: ../source/book.xml:8235
5899 msgid "The <command>svn switch</command> command also takes a <option>--revision</option> (<option>-r</option>) option, so you need not always move your working copy to the <literal>HEAD</literal> of the branch."
5903 #: ../source/book.xml:8239
5904 msgid "Of course, most projects are more complicated than our <filename>calc</filename> example, containing multiple subdirectories. Subversion users often follow a specific algorithm when using branches:"
5908 #: ../source/book.xml:8245
5909 msgid "Copy the project's entire <quote>trunk</quote> to a new branch directory."
5913 #: ../source/book.xml:8249
5914 msgid "Switch only <emphasis>part</emphasis> of the trunk working copy to mirror the branch."
5918 #: ../source/book.xml:8253
5919 msgid "In other words, if a user knows that the branch-work only needs to happen on a specific subdirectory, they use <command>svn switch</command> to move only that subdirectory to the branch. (Or sometimes users will switch just a single working file to the branch!) That way, they can continue to receive normal <quote>trunk</quote> updates to most of their working copy, but the switched portions will remain immune (unless someone commits a change to their branch). This feature adds a whole new dimension to the concept of a <quote>mixed working copy</quote>—not only can working copies contain a mixture of working revisions, but a mixture of repository locations as well."
5923 #: ../source/book.xml:8265
5924 msgid "If your working copy contains a number of switched subtrees from different repository locations, it continues to function as normal. When you update, you'll receive patches to each subtree as appropriate. When you commit, your local changes will still be applied as a single, atomic change to the repository."
5928 #: ../source/book.xml:8276
5929 msgid "You <emphasis>can</emphasis>, however, use <command>svn switch</command> with the <option>--relocate</option> option if the URL of your server changes and you don't want to abandon an existing working copy. See <xref linkend=\"svn.ref.svn.c.switch\"/> for more information and an example."
5933 #: ../source/book.xml:8270
5934 msgid "Note that while it's okay for your working copy to reflect a mixture of repository locations, these locations must all be within the <emphasis>same</emphasis> repository. Subversion repositories aren't yet able to communicate with one another; that's a feature planned for the future. <placeholder-1/>"
5938 #: ../source/book.xml:8283
5939 msgid "Switches and Updates"
5943 #: ../source/book.xml:8285
5944 msgid "Have you noticed that the output of <command>svn switch</command> and <command>svn update</command> look the same? The <literal>switch</literal> command is actually a superset of the update command."
5948 #: ../source/book.xml:8289
5949 msgid "When you run <command>svn update</command>, you're asking the repository to compare two trees. The repository does so, and then sends a description of the differences back to the client. The only difference between <command>svn switch</command> and <command>svn update</command> is that the <literal>update</literal> command always compares two identical paths."
5953 #: ../source/book.xml:8296
5954 msgid "That is, if your working copy is a mirror of <filename>/calc/trunk</filename>, then <command>svn update</command> will automatically compare your working copy of <filename>/calc/trunk</filename> to <filename>/calc/trunk</filename> in the <literal>HEAD</literal> revision. If you're switching your working copy to a branch, then <command>svn switch</command> will compare your working copy of <filename>/calc/trunk</filename> to some <emphasis>other</emphasis> branch-directory in the <literal>HEAD</literal> revision."
5958 #: ../source/book.xml:8307
5959 msgid "In other words, an update moves your working copy through time. A switch moves your working copy through time <emphasis>and</emphasis> space."
5963 #: ../source/book.xml:8311
5964 msgid "Because <command>svn switch</command> is essentially a variant of <command>svn update</command>, it shares the same behaviors; any local modifications in your working copy are preserved when new data arrives from the repository. This allows you to perform all sorts of clever tricks."
5968 #: ../source/book.xml:8316
5969 msgid "For example, suppose you have a working copy of <filename>/calc/trunk</filename> and make a number of changes to it. Then you suddenly realize that you meant to make the changes to a branch instead. No problem! When you <command>svn switch</command> your working copy to the branch, the local changes will remain. You can then test and commit them to the branch."
5973 #: ../source/book.xml:8329
5978 #: ../source/book.xml:8331
5979 msgid "Another common version control concept is a <firstterm>tag</firstterm>. A tag is just a <quote>snapshot</quote> of a project in time. In Subversion, this idea already seems to be everywhere. Each repository revision is exactly that—a snapshot of the filesystem after each commit."
5983 #: ../source/book.xml:8337
5984 msgid "However, people often want to give more human-friendly names to tags, like <literal>release-1.0</literal>. And they want to make snapshots of smaller subdirectories of the filesystem. After all, it's not so easy to remember that release-1.0 of a piece of software is a particular subdirectory of revision 4822."
5988 #: ../source/book.xml:8346
5989 msgid "Creating a Simple Tag"
5993 #: ../source/book.xml:8348
5994 msgid "Once again, <command>svn copy</command> comes to the rescue. If you want to create a snapshot of <filename>/calc/trunk</filename> exactly as it looks in the <literal>HEAD</literal> revision, then make a copy of it:"
5998 #: ../source/book.xml:8352
6000 msgid "\n$ svn copy http://svn.example.com/repos/calc/trunk \\\n http://svn.example.com/repos/calc/tags/release-1.0 \\\n -m \"Tagging the 1.0 release of the 'calc' project.\"\n\nCommitted revision 351.\n"
6004 #: ../source/book.xml:8359
6005 msgid "This example assumes that a <filename>/calc/tags</filename> directory already exists. (If it doesn't, you can create it using <command>svn mkdir</command>.) After the copy completes, the new <filename>release-1.0</filename> directory is forever a snapshot of how the project looked in the <literal>HEAD</literal> revision at the time you made the copy. Of course you might want to be more precise about exactly which revision you copy, in case somebody else may have committed changes to the project when you weren't looking. So if you know that revision 350 of <filename>/calc/trunk</filename> is exactly the snapshot you want, you can specify it by passing <option>-r 350</option> to the <command>svn copy</command> command."
6009 #: ../source/book.xml:8373
6010 msgid "But wait a moment: isn't this tag-creation procedure the same procedure we used to create a branch? Yes, in fact, it is. In Subversion, there's no difference between a tag and a branch. Both are just ordinary directories that are created by copying. Just as with branches, the only reason a copied directory is a <quote>tag</quote> is because <emphasis>humans</emphasis> have decided to treat it that way: as long as nobody ever commits to the directory, it forever remains a snapshot. If people start committing to it, it becomes a branch."
6014 #: ../source/book.xml:8383
6015 msgid "If you are administering a repository, there are two approaches you can take to managing tags. The first approach is <quote>hands off</quote>: as a matter of project policy, decide where your tags will live, and make sure all users know how to treat the directories they copy in there. (That is, make sure they know not to commit to them.) The second approach is more paranoid: you can use one of the access-control scripts provided with Subversion to prevent anyone from doing anything but creating new copies in the tags-area (See <xref linkend=\"svn.serverconfig\"/>.) The paranoid approach, however, isn't usually necessary. If a user accidentally commits a change to a tag-directory, you can simply undo the change as discussed in the previous section. This is version control, after all."
6019 #: ../source/book.xml:8401
6020 msgid "Creating a Complex Tag"
6024 #: ../source/book.xml:8403
6025 msgid "Sometimes you may want your <quote>snapshot</quote> to be more complicated than a single directory at a single revision."
6029 #: ../source/book.xml:8406
6030 msgid "For example, pretend your project is much larger than our <filename>calc</filename> example: suppose it contains a number of subdirectories and many more files. In the course of your work, you may decide that you need to create a working copy that is designed to have specific features and bug fixes. You can accomplish this by selectively backdating files or directories to particular revisions (using <command>svn update -r</command> liberally), or by switching files and directories to particular branches (making use of <command>svn switch</command>). When you're done, your working copy is a hodgepodge of repository locations from different revisions. But after testing, you know it's the precise combination of data you need."
6034 #: ../source/book.xml:8419
6035 msgid "Time to make a snapshot. Copying one URL to another won't work here. In this case, you want to make a snapshot of your exact working copy arrangement and store it in the repository. Luckily, <command>svn copy</command> actually has four different uses (which you can read about in <xref linkend=\"svn.ref\"/>), including the ability to copy a working-copy tree to the repository:"
6039 #: ../source/book.xml:8425
6041 msgid "\n$ ls\nmy-working-copy/\n\n$ svn copy my-working-copy http://svn.example.com/repos/calc/tags/mytag\n\nCommitted revision 352.\n"
6045 #: ../source/book.xml:8433
6046 msgid "Now there is a new directory in the repository, <filename>/calc/tags/mytag</filename>, which is an exact snapshot of your working copy—mixed revisions, URLs, and all."
6050 #: ../source/book.xml:8437
6051 msgid "Other users have found interesting uses for this feature. Sometimes there are situations where you have a bunch of local changes made to your working copy, and you'd like a collaborator to see them. Instead of running <command>svn diff</command> and sending a patch file (which won't capture tree changes, symlink changes or changes in properties), you can instead use <command>svn copy</command> to <quote>upload</quote> your working copy to a private area of the repository. Your collaborator can then either check out a verbatim copy of your working copy, or use <command>svn merge</command> to receive your exact changes."
6055 #: ../source/book.xml:8448
6056 msgid "While this is a nice method for uploading a quick snapshot of your working copy, note that this is <emphasis>not</emphasis> a good way to initially create a branch. Branch creation should be an event onto itself, and this method conflates the creation of a branch with extra changes to files, all within a single revision. This makes it very difficult (later on) to identify a single revision number as a branch point."
6060 #: ../source/book.xml:8456
6061 msgid "Have you ever found yourself making some complex edits (in your <filename>/trunk</filename> working copy) and suddenly realized, <quote>hey, these changes ought to be in their own branch?</quote> A great technique to do this can be summarized in two steps:"
6065 #: ../source/book.xml:8461
6067 msgid "\n$ svn copy http://svn.example.com/repos/calc/trunk \\\n http://svn.example.com/repos/calc/branches/newbranch\nCommitted revision 353.\n\n$ svn switch http://svn.example.com/repos/calc/branches/newbranch\nAt revision 353.\n"
6071 #: ../source/book.xml:8469
6072 msgid "The <command>svn switch</command> command, like <command>svn update</command>, preserves your local edits. At this point, your working copy is now a reflection of the newly created branch, and your next <command>svn commit</command> invocation will send your changes there."
6076 #: ../source/book.xml:8483
6077 msgid "Branch Maintenance"
6081 #: ../source/book.xml:8485
6082 msgid "You may have noticed by now that Subversion is extremely flexible. Because it implements branches and tags with the same underlying mechanism (directory copies), and because branches and tags appear in normal filesystem space, many people find Subversion intimidating. It's almost <emphasis>too</emphasis> flexible. In this section, we'll offer some suggestions for arranging and managing your data over time."
6086 #: ../source/book.xml:8495
6087 msgid "Repository Layout"
6091 #: ../source/book.xml:8497
6092 msgid "There are some standard, recommended ways to organize a repository. Most people create a <filename>trunk</filename> directory to hold the <quote>main line</quote> of development, a <filename>branches</filename> directory to contain branch copies, and a <filename>tags</filename> directory to contain tag copies. If a repository holds only one project, then often people create these top-level directories:"
6096 #: ../source/book.xml:8504
6098 msgid "\n/trunk\n/branches\n/tags\n"
6102 #: ../source/book.xml:8509
6103 msgid "If a repository contains multiple projects, admins typically index their layout by project (see <xref linkend=\"svn.reposadmin.projects.chooselayout\"/> to read more about <quote>project roots</quote>):"
6107 #: ../source/book.xml:8512
6109 msgid "\n/paint/trunk\n/paint/branches\n/paint/tags\n/calc/trunk\n/calc/branches\n/calc/tags\n"
6113 #: ../source/book.xml:8520
6114 msgid "Of course, you're free to ignore these common layouts. You can create any sort of variation, whatever works best for you or your team. Remember that whatever you choose, it's not a permanent commitment. You can reorganize your repository at any time. Because branches and tags are ordinary directories, the <command>svn move</command> command can move or rename them however you wish. Switching from one layout to another is just a matter of issuing a series of server-side moves; if you don't like the way things are organized in the repository, just juggle the directories around."
6118 #: ../source/book.xml:8530
6119 msgid "Remember, though, that while moving directories may be easy to do, you need to be considerate of your users as well. Your juggling can be disorienting to users with existing working copies. If a user has a working copy of a particular repository directory, your <command>svn move</command> operation might remove the path from the latest revision. When the user next runs <command>svn update</command>, she will be told that her working copy represents a path that no longer exists, and the user will be forced to <command>svn switch</command> to the new location."
6123 #: ../source/book.xml:8545
6124 msgid "Data Lifetimes"
6128 #: ../source/book.xml:8547
6129 msgid "Another nice feature of Subversion's model is that branches and tags can have finite lifetimes, just like any other versioned item. For example, suppose you eventually finish all your work on your personal branch of the <filename>calc</filename> project. After merging all of your changes back into <filename>/calc/trunk</filename>, there's no need for your private branch directory to stick around anymore:"
6133 #: ../source/book.xml:8555
6135 msgid "\n$ svn delete http://svn.example.com/repos/calc/branches/my-calc-branch \\\n -m \"Removing obsolete branch of calc project.\"\n\nCommitted revision 375.\n"
6139 #: ../source/book.xml:8561
6140 msgid "And now your branch is gone. Of course it's not really gone: the directory is simply missing from the <literal>HEAD</literal> revision, no longer distracting anyone. If you use <command>svn checkout</command>, <command>svn switch</command>, or <command>svn list</command> to examine an earlier revision, you'll still be able to see your old branch."
6144 #: ../source/book.xml:8568
6145 msgid "If browsing your deleted directory isn't enough, you can always bring it back. Resurrecting data is very easy in Subversion. If there's a deleted directory (or file) that you'd like to bring back into <literal>HEAD</literal>, simply use <command>svn copy -r</command> to copy it from the old revision:"
6149 #: ../source/book.xml:8574
6151 msgid "\n$ svn copy -r 374 http://svn.example.com/repos/calc/branches/my-calc-branch \\\n http://svn.example.com/repos/calc/branches/my-calc-branch\n\nCommitted revision 376.\n"
6155 #: ../source/book.xml:8580
6156 msgid "In our example, your personal branch had a relatively short lifetime: you may have created it to fix a bug or implement a new feature. When your task is done, so is the branch. In software development, though, it's also common to have two <quote>main</quote> branches running side-by-side for very long periods. For example, suppose it's time to release a stable version of the <filename>calc</filename> project to the public, and you know it's going to take a couple of months to shake bugs out of the software. You don't want people to add new features to the project, but you don't want to tell all developers to stop programming either. So instead, you create a <quote>stable</quote> branch of the software that won't change much:"
6160 #: ../source/book.xml:8593
6162 msgid "\n$ svn copy http://svn.example.com/repos/calc/trunk \\\n http://svn.example.com/repos/calc/branches/stable-1.0 \\\n -m \"Creating stable branch of calc project.\"\n\nCommitted revision 377.\n"
6166 #: ../source/book.xml:8600
6167 msgid "And now developers are free to continue adding cutting-edge (or experimental) features to <filename>/calc/trunk</filename>, and you can declare a project policy that only bug fixes are to be committed to <filename>/calc/branches/stable-1.0</filename>. That is, as people continue to work on the trunk, a human selectively ports bug fixes over to the stable branch. Even after the stable branch has shipped, you'll probably continue to maintain the branch for a long time—that is, as long as you continue to support that release for customers."
6171 #: ../source/book.xml:8617
6172 msgid "Vendor branches"
6176 #: ../source/book.xml:8619
6177 msgid "As is especially the case when developing software, the data that you maintain under version control is often closely related to, or perhaps dependent upon, someone else's data. Generally, the needs of your project will dictate that you stay as up-to-date as possible with the data provided by that external entity without sacrificing the stability of your own project. This scenario plays itself out all the time—anywhere that the information generated by one group of people has a direct effect on that which is generated by another group."
6181 #: ../source/book.xml:8628
6182 msgid "For example, software developers might be working on an application which makes use of a third-party library. Subversion has just such a relationship with the Apache Portable Runtime library (see <xref linkend=\"svn.developer.usingapi.apr\"/>). The Subversion source code depends on the APR library for all its portability needs. In earlier stages of Subversion's development, the project closely tracked APR's changing API, always sticking to the <quote>bleeding edge</quote> of the library's code churn. Now that both APR and Subversion have matured, Subversion attempts to synchronize with APR's library API only at well-tested, stable release points."
6186 #: ../source/book.xml:8639
6187 msgid "Now, if your project depends on someone else's information, there are several ways that you could attempt to synchronize that information with your own. Most painfully, you could issue oral or written instructions to all the contributors of your project, telling them to make sure that they have the specific versions of that third-party information that your project needs. If the third-party information is maintained in a Subversion repository, you could also use Subversion's externals definitions to effectively <quote>pin down</quote> specific versions of that information to some location in your own working copy directory (see <xref linkend=\"svn.advanced.externals\"/>)."
6191 #: ../source/book.xml:8650
6192 msgid "But sometimes you want to maintain custom modifications to third-party data in your own version control system. Returning to the software development example, programmers might need to make modifications to that third-party library for their own purposes. These modifications might include new functionality or bug fixes, maintained internally only until they become part of an official release of the third-party library. Or the changes might never be relayed back to the library maintainers, existing solely as custom tweaks to make the library further suit the needs of the software developers."
6196 #: ../source/book.xml:8660
6197 msgid "Now you face an interesting situation. Your project could house its custom modifications to the third-party data in some disjointed fashion, such as using patch files or full-fledged alternate versions of files and directories. But these quickly become maintenance headaches, requiring some mechanism by which to apply your custom changes to the third-party data, and necessitating regeneration of those changes with each successive version of the third-party data that you track."
6201 #: ../source/book.xml:8668
6202 msgid "The solution to this problem is to use <firstterm>vendor branches</firstterm>. A vendor branch is a directory tree in your own version control system that contains information provided by a third-party entity, or vendor. Each version of the vendor's data that you decide to absorb into your project is called a <firstterm>vendor drop</firstterm>."
6206 #: ../source/book.xml:8674
6207 msgid "Vendor branches provide two benefits. First, by storing the currently supported vendor drop in your own version control system, the members of your project never need to question whether they have the right version of the vendor's data. They simply receive that correct version as part of their regular working copy updates. Secondly, because the data lives in your own Subversion repository, you can store your custom changes to it in-place—you have no more need of an automated (or worse, manual) method for swapping in your customizations."
6211 #: ../source/book.xml:8686
6212 msgid "General Vendor Branch Management Procedure"
6216 #: ../source/book.xml:8688
6217 msgid "Managing vendor branches generally works like this. You create a top-level directory (such as <filename>/vendor</filename>) 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, <filename>/trunk</filename>) 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 <filename>/trunk</filename>, resolving whatever conflicts occur between your local changes and the upstream changes."
6221 #: ../source/book.xml:8701
6222 msgid "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 <filename>libcomplex</filename>, and our code drops will go into a subdirectory of our vendor branch called <filename>current</filename>. And since <command>svn import</command> creates all the intermediate parent directories it needs, we can actually accomplish both of these steps with a single command."
6226 #: ../source/book.xml:8713
6228 msgid "\n$ svn import /path/to/libcomplex-1.0 \\\n http://svn.example.com/repos/vendor/libcomplex/current \\\n -m 'importing initial 1.0 vendor drop'\n…\n"
6232 #: ../source/book.xml:8719
6233 msgid "We now have the current version of the libcomplex source code in <filename>/vendor/libcomplex/current</filename>. Now, we tag that version (see <xref linkend=\"svn.branchmerge.tags\"/>) and then copy it into the main development branch. Our copy will create a new directory called <filename>libcomplex</filename> in our existing <filename>calc</filename> project directory. It is in this copied version of the vendor data that we will make our customizations."
6237 #: ../source/book.xml:8728
6239 msgid "\n$ svn copy http://svn.example.com/repos/vendor/libcomplex/current \\\n http://svn.example.com/repos/vendor/libcomplex/1.0 \\\n -m 'tagging libcomplex-1.0'\n…\n$ svn copy http://svn.example.com/repos/vendor/libcomplex/1.0 \\\n http://svn.example.com/repos/calc/libcomplex \\\n -m 'bringing libcomplex-1.0 into the main branch'\n…\n"
6243 #: ../source/book.xml:8743
6244 msgid "And entirely bug-free, of course!"
6248 #: ../source/book.xml:8738
6249 msgid "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. <placeholder-1/>"
6253 #: ../source/book.xml:8745
6254 msgid "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."
6258 #: ../source/book.xml:8757
6259 msgid "To perform this upgrade, we check out a copy of our vendor branch, and replace the code in the <filename>current</filename> 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 <filename>current</filename> 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."
6263 #: ../source/book.xml:8768
6264 msgid "After replacing the 1.0 code with 1.1 code, <command>svn status</command> 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 <command>svn add</command> 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 <command>svn delete</command>. Finally, once our <filename>current</filename> working copy contains only the libcomplex 1.1 code, we commit the changes we made to get it looking that way."
6268 #: ../source/book.xml:8780
6269 msgid "Our <filename>current</filename> 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."
6273 #: ../source/book.xml:8786
6275 msgid "\n$ cd working-copies/calc\n$ svn merge http://svn.example.com/repos/vendor/libcomplex/1.0 \\\n http://svn.example.com/repos/vendor/libcomplex/current \\\n libcomplex\n… # resolve all the conflicts between their changes and our changes\n$ svn commit -m 'merging libcomplex-1.1 into the main branch'\n…\n"
6279 #: ../source/book.xml:8795
6280 msgid "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."
6284 #: ../source/book.xml:8804
6285 msgid "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."
6289 #: ../source/book.xml:8825
6290 msgid "svn_load_dirs.pl"
6294 #: ../source/book.xml:8828
6295 msgid "Vendor drops that contain more than a few deletes, additions and moves complicate the process of upgrading to each successive version of the third-party data. So Subversion supplies the <command>svn_load_dirs.pl</command> script to assist with this process. This script automates the importing steps we mentioned in the general vendor branch management procedure to make sure that mistakes are minimized. You will still be responsible for using the merge commands to merge the new versions of the third-party data into your main development branch, but <command>svn_load_dirs.pl</command> can help you more quickly and easily arrive at that stage."
6299 #: ../source/book.xml:8840
6300 msgid "In short, <command>svn_load_dirs.pl</command> is an enhancement to <command>svn import</command> that has several important characteristics:"
6304 #: ../source/book.xml:8845
6305 msgid "It can be run at any point in time to bring an existing directory in the repository to exactly match an external directory, performing all the necessary adds and deletes, and optionally performing moves, too."
6309 #: ../source/book.xml:8851
6310 msgid "It takes care of complicated series of operations between which Subversion requires an intermediate commit—such as before renaming a file or directory twice."
6314 #: ../source/book.xml:8856
6315 msgid "It will optionally tag the newly imported directory."
6319 #: ../source/book.xml:8859
6320 msgid "It will optionally add arbitrary properties to files and directories that match a regular expression."
6324 #: ../source/book.xml:8863
6325 msgid "<command>svn_load_dirs.pl</command> takes three mandatory arguments. The first argument is the URL to the base Subversion directory to work in. This argument is followed by the URL—relative to the first argument—into which the current vendor drop will be imported. Finally, the third argument is the local directory to import. Using our previous example, a typical run of <command>svn_load_dirs.pl</command> might look like:"
6329 #: ../source/book.xml:8871
6331 msgid "\n$ svn_load_dirs.pl http://svn.example.com/repos/vendor/libcomplex \\\n current \\\n /path/to/libcomplex-1.1\n…\n"
6335 #: ../source/book.xml:8877
6336 msgid "You can indicate that you'd like <command>svn_load_dirs.pl</command> to tag the new vendor drop by passing the <option>-t</option> command-line option and specifying a tag name. This tag is another URL relative to the first program argument."
6340 #: ../source/book.xml:8882
6342 msgid "\n$ svn_load_dirs.pl -t libcomplex-1.1 \\\n http://svn.example.com/repos/vendor/libcomplex \\\n current \\\n /path/to/libcomplex-1.1\n…\n"
6346 #: ../source/book.xml:8889
6347 msgid "When you run <command>svn_load_dirs.pl</command>, it examines the contents of your existing <quote>current</quote> vendor drop, and compares them with the proposed new vendor drop. In the trivial case, there will be no files that are in one version and not the other, and the script will perform the new import without incident. If, however, there are discrepancies in the file layouts between versions, <command>svn_load_dirs.pl</command> will ask you how to resolve those differences. For example, you will have the opportunity to tell the script that you know that the file <filename>math.c</filename> in version 1.0 of libcomplex was renamed to <filename>arithmetic.c</filename> in libcomplex 1.1. Any discrepancies not explained by moves are treated as regular additions and deletions."
6351 #: ../source/book.xml:8903
6352 msgid "The script also accepts a separate configuration file for setting properties on files and directories matching a regular expression that are <emphasis>added</emphasis> to the repository. This configuration file is specified to <command>svn_load_dirs.pl</command> using the <option>-p</option> command-line option. Each line of the configuration file is a whitespace-delimited set of two or four values: a Perl-style regular expression to match the added path against, a control keyword (either <literal>break</literal> or <literal>cont</literal>), and then optionally a property name and value."
6356 #: ../source/book.xml:8914
6358 msgid "\n\\.png$ break svn:mime-type image/png\n\\.jpe?g$ break svn:mime-type image/jpeg\n\\.m3u$ cont svn:mime-type audio/x-mpegurl\n\\.m3u$ break svn:eol-style LF\n.* break svn:eol-style native\n"
6362 #: ../source/book.xml:8921
6363 msgid "For each added path, the configured property changes whose regular expression matches the path are applied in order, unless the control specification is <literal>break</literal> (which means that no more property changes should be applied to that path). If the control specification is <literal>cont</literal>—an abbreviation for <literal>continue</literal>—then matching will continue with the next line of the configuration file."
6367 #: ../source/book.xml:8929
6368 msgid "Any whitespace in the regular expression, property name, or property value must be surrounded by either single or double quote characters. You can escape quote characters that are not used for wrapping whitespace by preceding them with a backslash (<literal>\\</literal>) character. The backslash escapes only quotes when parsing the configuration file, so do not protect any other characters beyond what is necessary for the regular expression."
6372 #: ../source/book.xml:8946
6373 msgid "We've covered a lot of ground in this chapter. We've discussed the concepts of tags and branches, and demonstrated how Subversion implements these concepts by copying directories with the <command>svn copy</command> command. We've shown how to use <command>svn merge</command> to copy changes from one branch to another, or roll back bad changes. We've gone over the use of <command>svn switch</command> to create mixed-location working copies. And we've talked about how one might manage the organization and lifetimes of branches in a repository."
6377 #: ../source/book.xml:8956
6378 msgid "Remember the Subversion mantra: branches and tags are cheap. So use them liberally! At the same time, don't forget to use good merging habits. Cheap copies are only useful when you're careful about tracking your merging actions."
6382 #: ../source/book.xml:8969
6383 msgid "Repository Administration"
6387 #: ../source/book.xml:8971
6388 msgid "The Subversion repository is the central storehouse of all your versioned data. As such, it becomes an obvious candidate for all the love and attention an administrator can offer. While the repository is generally a low-maintenance item, it is important to understand how to properly configure and care for it so that potential problems are avoided, and actual problems are safely resolved."
6392 #: ../source/book.xml:8978
6393 msgid "In this chapter, we'll discuss how to create and configure a Subversion repository. We'll also talk about repository maintenance, providing examples of how and when to use the <command>svnlook</command> and <command>svnadmin</command> tools provided with Subversion. We'll address some common questions and mistakes, and give some suggestions on how to arrange the data in the repository."
6397 #: ../source/book.xml:8990
6398 msgid "This may sound really prestigious and lofty, but we're just talking about anyone who is interested in that mysterious realm beyond the working copy where everyone's data hangs out."
6402 #: ../source/book.xml:8985
6403 msgid "If you plan to access a Subversion repository only in the role of a user whose data is under version control (that is, via a Subversion client), you can skip this chapter altogether. However, if you are, or wish to become, a Subversion repository administrator, <placeholder-1/> this chapter is for you."
6407 #: ../source/book.xml:9000
6408 msgid "The Subversion Repository, Defined"
6412 #: ../source/book.xml:9002
6413 msgid "Before jumping into the broader topic of repository administration, let's further define what a repository is. How does it look? How does it feel? Does it take its tea hot or iced, sweetened, and with lemon? As an administrator, you'll be expected to understand the composition of a repository both from a literal, OS-level perspective—how a repository looks and acts with respect to non-Subversion tools—and from a logical perspective—dealing with how data is represented <emphasis>inside</emphasis> the repository."
6417 #: ../source/book.xml:9011
6418 msgid "Seen through the eyes of a typical file browser application (such as the Windows Explorer) or command-line based filesystem navigation tools, the Subversion repository is just another directory full of stuff. There are some subdirectories with human-readable configuration files in them, some subdirectories with some not-so-human-readable data files, and so on. As in other areas of the Subversion design, modularity is given high regard, and hierarchical organization is preferred to cluttered chaos. So a shallow glance into a typical repository from a nuts-and-bolts perspective is sufficient to reveal the basic components of the repository:"
6422 #: ../source/book.xml:9022
6424 msgid "\n$ ls repos\nconf/ dav/ db/ format hooks/ locks/ README.txt\n"
6428 #: ../source/book.xml:9026
6429 msgid "Here's a quick fly-by overview of what exactly you're seeing in this directory listing. (Don't get bogged down in the terminology—detailed coverage of these components exists elsewhere in this and other chapters.)"
6433 #: ../source/book.xml:9032
6438 #: ../source/book.xml:9034
6439 msgid "A directory containing repository configuration files."
6443 #: ../source/book.xml:9038
6448 #: ../source/book.xml:9040
6449 msgid "A directory provided to mod_dav_svn for its private housekeeping data."
6453 #: ../source/book.xml:9045
6458 #: ../source/book.xml:9047
6459 msgid "The data store for all of your versioned data."
6463 #: ../source/book.xml:9051
6468 #: ../source/book.xml:9053
6469 msgid "A file that contains a single integer that indicates the version number of the repository layout."
6472 #.(term), (secondary)
6473 #: ../source/book.xml:9058 ../source/book.xml:23555 ../source/book.xml:23602 ../source/book.xml:23651 ../source/book.xml:23697 ../source/book.xml:23760 ../source/book.xml:23822 ../source/book.xml:23873 ../source/book.xml:23919 ../source/book.xml:23972
6478 #: ../source/book.xml:9060
6479 msgid "A directory full of hook script templates (and hook scripts themselves, once you've installed some)."
6483 #: ../source/book.xml:9065
6488 #: ../source/book.xml:9067
6489 msgid "A directory for Subversion's repository lock files, used for tracking accessors to the repository."
6493 #: ../source/book.xml:9072
6498 #: ../source/book.xml:9074
6499 msgid "A file whose contents merely inform its readers that they are looking at a Subversion repository."
6503 #: ../source/book.xml:9079
6504 msgid "Of course, when accessed via the Subversion libraries, this otherwise unremarkable collection of files and directories suddenly becomes an implementation of a virtual, versioned filesystem, complete with customizable event triggers. This filesystem has its own notions of directories and files, very similar to the notions of such things held by real filesystems (such as NTFS, FAT32, ext3, and so on). But this is a special filesystem—it hangs these directories and files from revisions, keeping all the changes you've ever made to them safely stored and forever accessible. This is where the entirety of your versioned data lives."
6508 #: ../source/book.xml:9096
6509 msgid "Strategies for Repository Deployment"
6513 #: ../source/book.xml:9098
6514 msgid "Due largely to the simplicity of the overall design of the Subversion repository and the technologies on which it relies, creating and configuring a repository are fairly straightforward tasks. There are a few preliminary decisions you'll want to make, but the actual work involved in any given setup of a Subversion repository is pretty straightforward, tending towards mindless repetition if you find yourself setting up multiples of these things."
6518 #: ../source/book.xml:9106
6519 msgid "Some things you'll want to consider up front, though, are:"
6523 #: ../source/book.xml:9109
6524 msgid "What data do you expect to live in your repository (or repositories), and how will that data be organized?"
6528 #: ../source/book.xml:9113
6529 msgid "Where will your repository live, and how will it be accessed?"
6533 #: ../source/book.xml:9117
6534 msgid "What types of access control and repository event reporting do you need?"
6538 #: ../source/book.xml:9121
6539 msgid "Which of the available types of data store do you want to use?"
6543 #: ../source/book.xml:9125
6544 msgid "In this section, we'll try to help you answer those questions."
6548 #: ../source/book.xml:9130
6549 msgid "Planning Your Repository Organization"
6553 #: ../source/book.xml:9132
6554 msgid "While Subversion allows you to move around versioned files and directories without any loss of information, and even provides ways of moving whole sets of versioned history from one repository to another, doing so can greatly disrupt the workflow of those who access the repository often and come to expect things to be at certain locations. So before creating a new repository, try to peer into the future a bit; plan ahead before placing your data under version control. By conscientiously <quote>laying out</quote> your repository or repositories and their versioned contents ahead of time, you can prevent many future headaches."
6558 #: ../source/book.xml:9143
6559 msgid "Let's assume that as repository administrator, you will be responsible for supporting the version control system for several projects. Your first decision is whether to use a single repository for multiple projects, or to give each project its own repository, or some compromise of these two."
6563 #: ../source/book.xml:9149
6564 msgid "There are benefits to using a single repository for multiple projects, most obviously the lack of duplicated maintenance. A single repository means that there is one set of hook programs, one thing to routinely backup, one thing to dump and load if Subversion releases an incompatible new version, and so on. Also, you can move data between projects easily, and without losing any historical versioning information."
6568 #: ../source/book.xml:9173
6569 msgid "Whether founded in ignorance or in poorly considered concepts about how to derive legitimate software development metrics, global revision numbers are a silly thing to fear, and <emphasis>not</emphasis> the kind of thing you should weigh when deciding how to arrange your projects and repositories."
6573 #: ../source/book.xml:9157
6574 msgid "The downside of using a single repository is that different projects may have different requirements in terms of the repository event triggers, such as needing to send commit notification emails to different mailing lists, or having different definitions about what does and does not constitute a legitimate commit. These aren't insurmountable problems, of course—it just means that all of your hook scripts have to be sensitive to the layout of your repository rather than assuming that the whole repository is associated with a single group of people. Also, remember that Subversion uses repository-global revision numbers. While those numbers don't have any particular magical powers, some folks still don't like the fact that even though no changes have been made to their project lately, the youngest revision number for the repository keeps climbing because other projects are actively adding new revisions. <placeholder-1/>"
6578 #: ../source/book.xml:9180
6579 msgid "A middle-ground approach can be taken, too. For example, projects can be grouped by how well they relate to each other. You might have a few repositories with a handful of projects in each repository. That way, projects that are likely to want to share data can do so easily, and as new revisions are added to the repository, at least the developers know that those new revisions are at least remotely related to everyone who uses that repository."
6583 #: ../source/book.xml:9205
6584 msgid "The <filename>trunk</filename>, <filename>tags</filename>, and <filename>branches</filename> trio are sometimes referred to as <quote>the TTB directories</quote>."
6588 #: ../source/book.xml:9188
6589 msgid "After deciding how to organize your projects with respect to repositories, you'll probably want to think about directory hierarchies within the repositories themselves. Because Subversion uses regular directory copies for branching and tagging (see <xref linkend=\"svn.branchmerge\"/>), the Subversion community recommends that you choose a repository location for each <firstterm>project root</firstterm>—the <quote>top-most</quote> directory which contains data related to that project—and then create three subdirectories beneath that root: <filename>trunk</filename>, meaning the directory under which the main project development occurs; <filename>branches</filename>, which is a directory in which to create various named branches of the main development line; <filename>tags</filename>, which is a collection of tree snapshots that are created, and perhaps destroyed, but never changed. <placeholder-1/>"
6593 #: ../source/book.xml:9209
6594 msgid "For example, your repository might look like:"
6598 #: ../source/book.xml:9210
6600 msgid "\n/\n calc/\n trunk/\n tags/\n branches/\n calendar/\n trunk/\n tags/\n branches/\n spreadsheet/\n trunk/\n tags/\n branches/\n …\n"
6604 #: ../source/book.xml:9226
6605 msgid "Note that it doesn't matter where in your repository each project root is. If you have only one project per repository, the logical place to put each project root is at the root of that project's respective repository. If you have multiple projects, you might want to arrange them in groups inside the repository, perhaps putting projects with similar goals or shared code in the same subdirectory, or maybe just grouping them alphabetically. Such an arrangement might look like:"
6609 #: ../source/book.xml:9235
6611 msgid "\n/\n utils/\n calc/\n trunk/\n tags/\n branches/\n calendar/\n trunk/\n tags/\n branches/\n …\n office/\n spreadsheet/\n trunk/\n tags/\n branches/\n …\n"
6615 #: ../source/book.xml:9254
6616 msgid "Lay out your repository in whatever way you see fit. Subversion does not expect or enforce a particular layout—in its eyes, a directory is a directory is a directory. Ultimately, you should choose the repository arrangement that meets the needs of the people who work on the projects that live there."
6620 #: ../source/book.xml:9260
6621 msgid "In the name of full disclosure, though, we'll mention another very common layout. In this layout, the <filename>trunk</filename>, <filename>tags</filename>, and <filename>branches</filename> directories live in the root directory of your repository, and your projects are in subdirectories beneath those, like:"
6625 #: ../source/book.xml:9266
6627 msgid "\n/\n trunk/\n calc/\n calendar/\n spreadsheet/\n …\n tags/\n calc/\n calendar/\n spreadsheet/\n …\n branches/\n calc/\n calendar/\n spreadsheet/\n …\n"
6631 #: ../source/book.xml:9284
6632 msgid "There's nothing particularly incorrect about such a layout, but it may or may not seem as intuitive for your users. Especially in large, multi-project situations with many users, those users may tend to be familiar with only one or two of the projects in the repository. But the projects-as-branch-siblings tends to de-emphasize project individuality and focus on the entire set of projects as a single entity. That's a social issue though. We like our originally suggested arrangement for purely practical reasons—it's easier to ask about (or modify, or migrate elsewhere) the entire history of a single project when there's a single repository path that holds the entire history—past, present, tagged, and branched—for that project and that project alone."
6636 #: ../source/book.xml:9302
6637 msgid "Deciding Where and How to Host Your Repository"
6641 #: ../source/book.xml:9304
6642 msgid "Before creating your Subversion repository, an obvious question you'll need to answer is where the thing is going to live. This is strongly connected to a myriad of other questions involving how the repository will be accessed (via a Subversion server or directly), by whom (users behind your corporate firewall or the whole world out on the open Internet), what other services you'll be providing around Subversion (repository browsing interfaces, e-mail based commit notification, etc.), your data backup strategy, and so on."
6646 #: ../source/book.xml:9314
6647 msgid "We cover server choice and configuration in <xref linkend=\"svn.serverconfig\"/>, but the point we'd like to briefly make here is simply that the answers to some of these other questions might have implications that force your hand when deciding where your repository will live. For example, certain deployment scenarios might require accessing the repository via a remote filesystem from multiple computers, in which case (as you'll read in the next section) your choice of a repository back-end data store turns out not to be a choice at all because only one of the available back-ends will work in this scenario."
6651 #: ../source/book.xml:9324
6652 msgid "Addressing each possible way to deploy Subversion is both impossible, and outside the scope of this book. We simply encourage you to evaluate your options using these pages and other sources as your reference material, and plan ahead."
6656 #: ../source/book.xml:9333
6657 msgid "Choosing a Data Store"
6661 #: ../source/book.xml:9346
6662 msgid "Often pronounced <quote>fuzz-fuzz</quote>, if Jack Repenning has anything to say about it. (This book, however, assumes that the reader is thinking <quote>eff-ess-eff-ess</quote>.)"
6666 #: ../source/book.xml:9335
6667 msgid "As of version 1.1, Subversion provides two options for the type of underlying data store—often referred to as <quote>the back-end</quote> or, somewhat confusingly, <quote>the (versioned) filesystem</quote>—that each repository uses. One type of data store keeps everything in a Berkeley DB (or BDB) database environment; repositories that use this type are often referred to as being <quote>BDB-backed</quote>. The other type stores data in ordinary flat files, using a custom format. Subversion developers have adopted the habit of referring to this latter data storage mechanism as <firstterm>FSFS</firstterm><placeholder-1/> —a versioned filesystem implementation that uses the native OS filesystem directly—rather than via a database library or some other abstraction layer—to store data."
6671 #: ../source/book.xml:9353
6672 msgid "<xref linkend=\"svn.reposadmin.basics.backends.tbl-1\"/> gives a comparative overview of Berkeley DB and FSFS repositories."
6676 #: ../source/book.xml:9358
6677 msgid "Repository Data Store Comparison"
6681 #: ../source/book.xml:9363
6686 #: ../source/book.xml:9364 ../source/book.xml:11719
6691 #: ../source/book.xml:9365 ../source/book.xml:9466
6696 #: ../source/book.xml:9366 ../source/book.xml:9582
6701 #: ../source/book.xml:9371
6706 #: ../source/book.xml:9372
6707 msgid "Data integrity"
6711 #: ../source/book.xml:9373
6712 msgid "when properly deployed, extremely reliable; Berkeley DB 4.4 brings auto-recovery"
6716 #: ../source/book.xml:9375
6717 msgid "older versions had some rarely demonstrated, but data-destroying bugs"
6721 #: ../source/book.xml:9379
6722 msgid "Sensitivity to interruptions"
6726 #: ../source/book.xml:9381
6731 #: ../source/book.xml:9380
6732 msgid "very; crashes and permission problems can leave the database <placeholder-1/>, requiring journaled recovery procedures"
6736 #: ../source/book.xml:9383
6737 msgid "quite insensitive"
6741 #: ../source/book.xml:9386
6742 msgid "Accessibility"
6746 #: ../source/book.xml:9387
6747 msgid "Usable from a read-only mount"
6751 #: ../source/book.xml:9388 ../source/book.xml:9393
6756 #: ../source/book.xml:9389 ../source/book.xml:9394 ../source/book.xml:9399
6761 #: ../source/book.xml:9392
6762 msgid "Platform-independent storage"
6766 #: ../source/book.xml:9397
6767 msgid "Usable over network filesystems"
6771 #: ../source/book.xml:9398
6772 msgid "generally, no"
6776 #: ../source/book.xml:9402
6777 msgid "Group permissions handling"
6781 #: ../source/book.xml:9403
6782 msgid "sensitive to user umask problems; best if accessed by only one user"
6786 #: ../source/book.xml:9405
6787 msgid "works around umask problems"
6791 #: ../source/book.xml:9408
6796 #: ../source/book.xml:9409
6797 msgid "Repository disk usage"
6801 #: ../source/book.xml:9410
6802 msgid "larger (especially if logfiles aren't purged)"
6806 #: ../source/book.xml:9411
6811 #: ../source/book.xml:9414
6812 msgid "Number of revision trees"
6816 #: ../source/book.xml:9415
6817 msgid "database; no problems"
6821 #: ../source/book.xml:9416
6822 msgid "some older native filesystems don't scale well with thousands of entries in a single directory"
6826 #: ../source/book.xml:9420
6827 msgid "Directories with many files"
6831 #: ../source/book.xml:9421
6836 #: ../source/book.xml:9422
6841 #: ../source/book.xml:9425
6846 #: ../source/book.xml:9426
6847 msgid "Checking out latest revision"
6851 #: ../source/book.xml:9427 ../source/book.xml:9428
6852 msgid "no meaningful difference"
6856 #: ../source/book.xml:9431
6857 msgid "Large commits"
6861 #: ../source/book.xml:9432
6862 msgid "slower overall, but cost is amortized across the lifetime of the commit"
6866 #: ../source/book.xml:9434
6867 msgid "faster overall, but finalization delay may cause client timeouts"
6871 #: ../source/book.xml:9440
6872 msgid "There are advantages and disadvantages to each of these two back-end types. Neither of them is more <quote>official</quote> than the other, though the newer FSFS is the default data store as of Subversion 1.2. Both are reliable enough to trust with your versioned data. But as you can see in <xref linkend=\"svn.reposadmin.basics.backends.tbl-1\"/>, the FSFS backend provides quite a bit more flexibility in terms of its supported deployment scenarios. More flexibility means you have to work a little harder to find ways to deploy it incorrectly. Those reasons—plus the fact that not using Berkeley DB means there's one fewer component in the system—largely explain why today almost everyone uses the FSFS backend when creating new repositories."
6876 #: ../source/book.xml:9453
6877 msgid "Fortunately, most programs which access Subversion repositories are blissfully ignorant of which back-end data store is in use. And you aren't even necessarily stuck with your first choice of a data store—in the event that you change your mind later, Subversion provides ways of migrating your repository's data into another repository that uses a different back-end data store. We talk more about that later in this chapter."
6881 #: ../source/book.xml:9461
6882 msgid "The following subsections provide a more detailed look at the available data store types."
6886 #: ../source/book.xml:9468
6887 msgid "When the initial design phase of Subversion was in progress, the developers decided to use Berkeley DB for a variety of reasons, including its open-source license, transaction support, reliability, performance, API simplicity, thread-safety, support for cursors, and so on."
6891 #: ../source/book.xml:9474
6892 msgid "Berkeley DB provides real transaction support—perhaps its most powerful feature. Multiple processes accessing your Subversion repositories don't have to worry about accidentally clobbering each other's data. The isolation provided by the transaction system is such that for any given operation, the Subversion repository code sees a static view of the database—not a database that is constantly changing at the hand of some other process—and can make decisions based on that view. If the decision made happens to conflict with what another process is doing, the entire operation is rolled back as if it never happened, and Subversion gracefully retries the operation against a new, updated (and yet still static) view of the database."
6896 #: ../source/book.xml:9488
6897 msgid "Another great feature of Berkeley DB is <firstterm>hot backups</firstterm>—the ability to backup the database environment without taking it <quote>offline</quote>. We'll discuss how to backup your repository in <xref linkend=\"svn.reposadmin.maint.backup\"/>, but the benefits of being able to make fully functional copies of your repositories without any downtime should be obvious."
6901 #: ../source/book.xml:9494
6902 msgid "Berkeley DB is also a very reliable database system when properly used. Subversion uses Berkeley DB's logging facilities, which means that the database first writes to on-disk log files a description of any modifications it is about to make, and then makes the modification itself. This is to ensure that if anything goes wrong, the database system can back up to a previous <firstterm>checkpoint</firstterm>—a location in the log files known not to be corrupt—and replay transactions until the data is restored to a usable state. See <xref linkend=\"svn.reposadmin.maint.diskspace\"/> for more about Berkeley DB log files."
6906 #: ../source/book.xml:9506
6907 msgid "But every rose has its thorn, and so we must note some known limitations of Berkeley DB. First, Berkeley DB environments are not portable. You cannot simply copy a Subversion repository that was created on a Unix system onto a Windows system and expect it to work. While much of the Berkeley DB database format is architecture independent, there are other aspects of the environment that are not. Secondly, Subversion uses Berkeley DB in a way that will not operate on Windows 95/98 systems—if you need to house a BDB-backed repository on a Windows machine, stick with Windows 2000 or newer."
6911 #: ../source/book.xml:9519
6912 msgid "Berkeley DB requires that the underlying filesystem implement strict POSIX locking semantics, and more importantly, the ability to map files directly into process memory."
6916 #: ../source/book.xml:9517
6917 msgid "While Berkeley DB promises to behave correctly on network shares that meet a particular set of specifications, <placeholder-1/> most networked filesystem types and appliances do <emphasis>not</emphasis> actually meet those requirements. And in no case can you allow a BDB-backed repository that resides on a network share to be accessed by multiple clients of that share at once (which quite often is the whole point of having the repository live on a network share in the first place)."
6921 #: ../source/book.xml:9531
6922 msgid "If you attempt to use Berkeley DB on a non-compliant remote filesystem, the results are unpredictable—you may see mysterious errors right away, or it may be months before you discover that your repository database is subtly corrupted. You should strongly consider using the FSFS data store for repositories that need to live on a network share."
6926 #: ../source/book.xml:9539
6927 msgid "Finally, because Berkeley DB is a library linked directly into Subversion, it's more sensitive to interruptions than a typical relational database system. Most SQL systems, for example, have a dedicated server process that mediates all access to tables. If a program accessing the database crashes for some reason, the database daemon notices the lost connection and cleans up any mess left behind. And because the database daemon is the only process accessing the tables, applications don't need to worry about permission conflicts. These things are not the case with Berkeley DB, however. Subversion (and programs using Subversion libraries) access the database tables directly, which means that a program crash can leave the database in a temporarily inconsistent, inaccessible state. When this happens, an administrator needs to ask Berkeley DB to restore to a checkpoint, which is a bit of an annoyance. Other things can cause a repository to <quote>wedge</quote> besides crashed processes, such as programs conflicting over ownership and permissions on the database files."
6931 #: ../source/book.xml:9559
6932 msgid "Berkeley DB 4.4 brings (to Subversion 1.4 and better) the ability for Subversion to automatically and transparently recover Berkeley DB environments in need of such recovery. When a Subversion process attaches to a repository's Berkeley DB environment, it uses some process accounting mechanisms to detect any unclean disconnections by previous processes, performs any necessary recovery, and then continues on as if nothing happened. This doesn't completely eliminate instances of repository wedging, but it does drastically reduce the amount of human interaction required to recover from them."
6936 #: ../source/book.xml:9571
6937 msgid "So while a Berkeley DB repository is quite fast and scalable, it's best used by a single server process running as one user—such as Apache's <command>httpd</command> or <command>svnserve</command> (see <xref linkend=\"svn.serverconfig\"/>)—rather than accessing it as many different users via <literal>file://</literal> or <literal>svn+ssh://</literal> URLs. If using a Berkeley DB repository directly as multiple users, be sure to read <xref linkend=\"svn.serverconfig.multimethod\"/>."
6941 #: ../source/book.xml:9584
6942 msgid "In mid-2004, a second type of repository storage system—one which doesn't use a database at all—came into being. An FSFS repository stores the changes associated with a revision in a single file, and so all of a repository's revisions can be found in a single subdirectory full of numbered files. Transactions are created in separate subdirectories as individual files. When complete, the transaction file is renamed and moved into the revisions directory, thus guaranteeing that commits are atomic. And because a revision file is permanent and unchanging, the repository also can be backed up while <quote>hot</quote>, just like a BDB-backed repository."
6946 #: ../source/book.xml:9597
6947 msgid "The FSFS revision files describe a revision's directory structure, file contents, and deltas against files in other revision trees. Unlike a Berkeley DB database, this storage format is portable across different operating systems and isn't sensitive to CPU architecture. Because there's no journaling or shared-memory files being used, the repository can be safely accessed over a network filesystem and examined in a read-only environment. The lack of database overhead also means that the overall repository size is a bit smaller."
6951 #: ../source/book.xml:9607
6952 msgid "FSFS has different performance characteristics too. When committing a directory with a huge number of files, FSFS is able to more quickly append directory entries. On the other hand, FSFS writes the latest version of a file as a delta against an earlier version, which means that checking out the latest tree is a bit slower than fetching the fulltexts stored in a Berkeley DB HEAD revision. FSFS also has a longer delay when finalizing a commit, which could in extreme cases cause clients to time out while waiting for a response."
6956 #: ../source/book.xml:9617
6957 msgid "The most important distinction, however, is FSFS's imperviousness to <quote>wedging</quote> when something goes wrong. If a process using a Berkeley DB database runs into a permissions problem or suddenly crashes, the database can be left in an unusable state until an administrator recovers it. If the same scenarios happen to a process using an FSFS repository, the repository isn't affected at all. At worst, some transaction data is left behind."
6961 #: ../source/book.xml:9629
6962 msgid "Oracle bought Sleepycat and its flagship software, Berkeley DB, on Valentine's Day in 2006."
6966 #: ../source/book.xml:9625
6967 msgid "The only real argument against FSFS is its relative immaturity compared to Berkeley DB. Unlike Berkeley DB, which has years of history, its own dedicated development team and, now, Oracle's mighty name attached to it, <placeholder-1/> FSFS is a much newer bit of engineering. Prior to Subversion 1.4, it was still shaking out some pretty serious data integrity bugs which, while only triggered in very rare cases, nonetheless did occur. That said, FSFS has quickly become the back-end of choice for some of the largest public and private Subversion repositories, and promises a lower barrier to entry for Subversion across the board."
6971 #: ../source/book.xml:9646
6972 msgid "Creating and Configuring Your Repository"
6976 #: ../source/book.xml:9648
6977 msgid "In <xref linkend=\"svn.reposadmin.planning\"/>, we looked at some of the important decisions that should be made before creating and configuring your Subversion repository. Now, we finally get to get our hands dirty! In this section, we'll see how to actually create a Subversion repository and configure it to perform custom actions when special repository events occur."
6981 #: ../source/book.xml:9658
6982 msgid "Creating the Repository"
6986 #: ../source/book.xml:9660
6987 msgid "Subversion repository creation is an incredibly simple task. The <command>svnadmin</command> utility that comes with Subversion provides a subcommand (<literal>create</literal>) for doing just that."
6991 #: ../source/book.xml:9664
6993 msgid "\n$ svnadmin create /path/to/repos\n"
6997 #: ../source/book.xml:9667
6998 msgid "This creates a new repository in the directory <filename>/path/to/repos</filename>, and with the default filesystem data store. Prior to Subversion 1.2, the default was to use Berkeley DB; the default is now FSFS. You can explicitly choose the filesystem type using the <option>--fs-type</option> argument, which accepts as a parameter either <literal>fsfs</literal> or <literal>bdb</literal>."
7002 #: ../source/book.xml:9675
7004 msgid "\n$ # Create an FSFS-backed repository\n$ svnadmin create --fs-type fsfs /path/to/repos\n$\n"
7008 #: ../source/book.xml:9680
7010 msgid "\n# Create a Berkeley-DB-backed repository\n$ svnadmin create --fs-type bdb /path/to/repos\n$\n"
7014 #: ../source/book.xml:9685
7015 msgid "After running this simple command, you have a Subversion repository."
7019 #: ../source/book.xml:9688
7020 msgid "The path argument to <command>svnadmin</command> is just a regular filesystem path and not a URL like the <command>svn</command> client program uses when referring to repositories. Both <command>svnadmin</command> and <command>svnlook</command> are considered server-side utilities—they are used on the machine where the repository resides to examine or modify aspects of the repository, and are in fact unable to perform tasks across a network. A common mistake made by Subversion newcomers is trying to pass URLs (even <quote>local</quote><literal>file://</literal> ones) to these two programs."
7024 #: ../source/book.xml:9700
7025 msgid "Present in the <filename>db/</filename> subdirectory of your repository is the implementation of the versioned filesystem. Your new repository's versioned filesystem begins life at revision 0, which is defined to consist of nothing but the top-level root (<filename>/</filename>) directory. Initially, revision 0 also has a single revision property, <literal>svn:date</literal>, set to the time at which the repository was created."
7029 #: ../source/book.xml:9708
7030 msgid "Now that you have a repository, it's time to customize it."
7034 #: ../source/book.xml:9711
7035 msgid "While some parts of a Subversion repository—such as the configuration files and hook scripts—are meant to be examined and modified manually, you shouldn't (and shouldn't need to) tamper with the other parts of the repository <quote>by hand</quote>. The <command>svnadmin</command> tool should be sufficient for any changes necessary to your repository, or you can look to third-party tools (such as Berkeley DB's tool suite) for tweaking relevant subsections of the repository. Do <emphasis>not</emphasis> attempt manual manipulation of your version control history by poking and prodding around in your repository's data store files!"
7039 #: ../source/book.xml:9728
7040 msgid "Implementing Repository Hooks"
7044 #: ../source/book.xml:9730
7045 msgid "A <firstterm>hook</firstterm> is a program triggered by some repository event, such as the creation of a new revision or the modification of an unversioned property. Some hooks (the so-called <quote>pre hooks</quote>) run in advance of a repository operation and provide a means by which to both report what is about to happen and to prevent it from happening at all. Other hooks (the <quote>post hooks</quote>) run after the completion of a repository event, and are useful for performing tasks that examine—but don't modify—the repository. Each hook is handed enough information to tell what that event is (or was), the specific repository changes proposed (or completed), and the username of the person who triggered the event."
7049 #: ../source/book.xml:9743
7050 msgid "The <filename>hooks</filename> subdirectory is, by default, filled with templates for various repository hooks."
7054 #: ../source/book.xml:9746
7056 msgid "\n$ ls repos/hooks/\npost-commit.tmpl\t post-unlock.tmpl pre-revprop-change.tmpl\npost-lock.tmpl\t\t pre-commit.tmpl pre-unlock.tmpl\npost-revprop-change.tmpl pre-lock.tmpl start-commit.tmpl\n"
7060 #: ../source/book.xml:9752
7061 msgid "There is one template for each hook that the Subversion repository supports, and by examining the contents of those template scripts, you can see what triggers each script to run and what data is passed to that script. Also present in many of these templates are examples of how one might use that script, in conjunction with other Subversion-supplied programs, to perform common useful tasks. To actually install a working hook, you need only place some executable program or script into the <filename>repos/hooks</filename> directory which can be executed as the name (like <command>start-commit</command> or <command>post-commit</command>) of the hook."
7065 #: ../source/book.xml:9764
7066 msgid "On Unix platforms, this means supplying a script or program (which could be a shell script, a Python program, a compiled C binary, or any number of other things) named exactly like the name of the hook. Of course, the template files are present for more than just informational purposes—the easiest way to install a hook on Unix platforms is to simply copy the appropriate template file to a new file that lacks the <literal>.tmpl</literal> extension, customize the hook's contents, and ensure that the script is executable. Windows, however, uses file extensions to determine whether or not a program is executable, so you would need to supply a program whose basename is the name of the hook, and whose extension is one of the special extensions recognized by Windows for executable programs, such as <filename>.exe</filename> for programs, and <filename>.bat</filename> for batch files."
7070 #: ../source/book.xml:9781
7071 msgid "For security reasons, the Subversion repository executes hook programs with an empty environment—that is, no environment variables are set at all, not even <literal>$PATH</literal> (or <literal>%PATH%</literal>, under Windows). Because of this, many administrators are baffled when their hook program runs fine by hand, but doesn't work when run by Subversion. Be sure to explicitly set any necessary environment variables in your hook program and/or use absolute paths to programs."
7075 #: ../source/book.xml:9791
7076 msgid "Subversion executes hooks as the same user who owns the process which is accessing the Subversion repository. In most cases, the repository is being accessed via a Subversion server, so this user is the same user as which that server runs on the system. The hooks themselves will need to be configured with OS-level permissions that allow that user to execute them. Also, this means that any file or programs (including the Subversion repository itself) accessed directly or indirectly by the hook will be accessed as the same user. In other words, be alert to potential permission-related problems that could prevent the hook from performing the tasks it is designed to perform."
7080 #: ../source/book.xml:9803
7081 msgid "There are nine hooks implemented by the Subversion repository, and you can get details about each of them in <xref linkend=\"svn.ref.reposhooks\"/>. As a repository administrator, you'll need to decide which of hooks you wish to implement (by way of providing an appropriately named and permissioned hook program), and how. When you make this decision, keep in mind the big picture of how your repository is deployed. For example, if you are using server configuration to determine which users are permitted to commit changes to your repository, then you don't need to do this sort of access control via the hook system."
7085 #: ../source/book.xml:9815
7086 msgid "There is no shortage of Subversion hook programs and scripts freely available either from the Subversion community itself or elsewhere. These scripts cover a wide range of utility—basic access control, policy adherence checking, issue tracker integration, email- or syndication-based commit notification, and beyond. See <xref linkend=\"svn.3rdparty\"/> for discussion of some of the most commonly used hook programs. Or, if you wish to write your own, see <xref linkend=\"svn.developer\"/>."
7090 #: ../source/book.xml:9824
7091 msgid "While hook scripts can do almost anything, there is one dimension in which hook script authors should show restraint: do <emphasis>not</emphasis> modify a commit transaction using hook scripts. While it might be tempting to use hook scripts to automatically correct errors or shortcomings or policy violations present in the files being committed, doing so can cause problems. Subversion keeps client-side caches of certain bits of repository data, and if you change a commit transaction in this way, those caches become indetectably stale. This inconsistency can lead to surprising and unexpected behavior. Instead of modifying the transaction, you should simply <emphasis>validate</emphasis> the transaction in the <filename>pre-commit</filename> hook and reject the commit if it does not meet the desired requirements. As a bonus, your users will learn the value of careful, compliance-minded work habits."
7095 #: ../source/book.xml:9846
7096 msgid "Berkeley DB Configuration"
7100 #: ../source/book.xml:9848
7101 msgid "A Berkeley DB environment is an encapsulation of one or more databases, log files, region files and configuration files. The Berkeley DB environment has its own set of default configuration values for things like the number of database locks allowed to be taken out at any given time, or the maximum size of the journaling log files, etc. Subversion's filesystem logic additionally chooses default values for some of the Berkeley DB configuration options. However, sometimes your particular repository, with its unique collection of data and access patterns, might require a different set of configuration option values."
7105 #: ../source/book.xml:9859
7106 msgid "The producers of Berkeley DB understand that different applications and database environments have different requirements, and so they have provided a mechanism for overriding at runtime many of the configuration values for the Berkeley DB environment: BDB checks for the presence of a file named <filename>DB_CONFIG</filename> in the environment directory (namely, the repository's <filename>db</filename> subdirectory), and parses the options found in that file . Subversion itself creates this file when it creates the rest of the repository. The file initially contains some default options, as well as pointers to the Berkeley DB online documentation so you can read about what those options do. Of course, you are free to add any of the supported Berkeley DB options to your <filename>DB_CONFIG</filename> file. Just be aware that while Subversion never attempts to read or interpret the contents of the file, and makes no direct use of the option settings in it, you'll want to avoid any configuration changes that may cause Berkeley DB to behave in a fashion that is at odds with what Subversion might expect. Also, changes made to <filename>DB_CONFIG</filename> won't take effect until you recover the database environment (using <command>svnadmin recover</command>)."
7110 #: ../source/book.xml:9888
7111 msgid "Repository Maintenance"
7115 #: ../source/book.xml:9890
7116 msgid "Maintaining a Subversion repository can be daunting, mostly due to the complexities inherent in systems which have a database backend. Doing the task well is all about knowing the tools—what they are, when to use them, and how to use them. This section will introduce you to the repository administration tools provided by Subversion, and how to wield them to accomplish tasks such as repository data migration, upgrades, backups and cleanups."
7120 #: ../source/book.xml:9901
7121 msgid "An Administrator's Toolkit"
7125 #: ../source/book.xml:9903
7126 msgid "Subversion provides a handful of utilities useful for creating, inspecting, modifying and repairing your repository. Let's look more closely at each of those tools. Afterward, we'll briefly examine some of the utilities included in the Berkeley DB distribution that provide functionality specific to your repository's database backend not otherwise provided by Subversion's own tools."
7130 #: ../source/book.xml:9915
7131 msgid "The <command>svnadmin</command> program is the repository administrator's best friend. Besides providing the ability to create Subversion repositories, this program allows you to perform several maintenance operations on those repositories. The syntax of <command>svnadmin</command> is similar to that of other Subversion command-line programs:"
7135 #: ../source/book.xml:9922
7137 msgid "\n$ svnadmin help\ngeneral usage: svnadmin SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]\nType 'svnadmin help <subcommand>' for help on a specific subcommand.\nType 'svnadmin --version' to see the program version and FS modules.\n\nAvailable subcommands:\n crashtest\n create\n deltify\n…\n"
7141 #: ../source/book.xml:9934
7142 msgid "We've already mentioned <command>svnadmin</command>'s <literal>create</literal> subcommand (see <xref linkend=\"svn.reposadmin.basics.creating\"/>). Most of the others we will cover later in this chapter. And you can consult <xref linkend=\"svn.ref.svnadmin\"/> for a full rundown of subcommands and what each of them offers."
7146 #: ../source/book.xml:9945
7147 msgid "<command>svnlook</command> is a tool provided by Subversion for examining the various revisions and <firstterm>transactions</firstterm> (which are revisions in-the-making) in a repository. No part of this program attempts to change the repository. <command>svnlook</command> is typically used by the repository hooks for reporting the changes that are about to be committed (in the case of the <command>pre-commit</command> hook) or that were just committed (in the case of the <command>post-commit</command> hook) to the repository. A repository administrator may use this tool for diagnostic purposes."
7151 #: ../source/book.xml:9956
7152 msgid "<command>svnlook</command> has a straightforward syntax:"
7156 #: ../source/book.xml:9958
7158 msgid "\n$ svnlook help\ngeneral usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]\nNote: any subcommand which takes the '--revision' and '--transaction'\n options will, if invoked without one of those options, act on\n the repository's youngest revision.\nType 'svnlook help <subcommand>' for help on a specific subcommand.\nType 'svnlook --version' to see the program version and FS modules.\n…\n"
7162 #: ../source/book.xml:9968
7163 msgid "Nearly every one of <command>svnlook</command>'s subcommands can operate on either a revision or a transaction tree, printing information about the tree itself, or how it differs from the previous revision of the repository. You use the <option>--revision (-r)</option> and <option>--transaction (-t)</option> options to specify which revision or transaction, respectively, to examine. In the absence of both the <option>--revision (-r)</option> and <option>--transaction (-t)</option> options, <command>svnlook</command> will examine the youngest (or <quote>HEAD</quote>) revision in the repository. So the following two commands do exactly the same thing when 19 is the youngest revision in the repository located at <filename>/path/to/repos</filename>:"
7167 #: ../source/book.xml:9982
7169 msgid "\n$ svnlook info /path/to/repos\n$ svnlook info /path/to/repos -r 19\n"
7173 #: ../source/book.xml:9986
7174 msgid "The only exception to these rules about subcommands is the <command>svnlook youngest</command> subcommand, which takes no options, and simply prints out the repository's youngest revision number."
7178 #: ../source/book.xml:9990
7180 msgid "\n$ svnlook youngest /path/to/repos\n19\n"
7184 #: ../source/book.xml:9995
7185 msgid "Keep in mind that the only transactions you can browse are uncommitted ones. Most repositories will have no such transactions, because transactions are usually either committed (in which case, you should access them as revision with the <option>--revision (-r)</option> option) or aborted and removed."
7189 #: ../source/book.xml:10002
7190 msgid "Output from <command>svnlook</command> is designed to be both human- and machine-parsable. Take as an example the output of the <literal>info</literal> subcommand:"
7194 #: ../source/book.xml:10005
7196 msgid "\n$ svnlook info /path/to/repos\nsally\n2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)\n27\nAdded the usual\nGreek tree.\n"
7200 #: ../source/book.xml:10013
7201 msgid "The output of the <literal>info</literal> subcommand is defined as:"
7205 #: ../source/book.xml:10017
7206 msgid "The author, followed by a newline."
7210 #: ../source/book.xml:10020
7211 msgid "The date, followed by a newline."
7215 #: ../source/book.xml:10023
7216 msgid "The number of characters in the log message, followed by a newline."
7220 #: ../source/book.xml:10027
7221 msgid "The log message itself, followed by a newline."
7225 #: ../source/book.xml:10030
7226 msgid "This output is human-readable, meaning items like the datestamp are displayed using a textual representation instead of something more obscure (such as the number of nanoseconds since the Tasty Freeze guy drove by). But the output is also machine-parsable—because the log message can contain multiple lines and be unbounded in length, <command>svnlook</command> provides the length of that message before the message itself. This allows scripts and other wrappers around this command to make intelligent decisions about the log message, such as how much memory to allocate for the message, or at least how many bytes to skip in the event that this output is not the last bit of data in the stream."
7230 #: ../source/book.xml:10043
7231 msgid "<command>svnlook</command> can perform a variety of other queries: displaying subsets of bits of information we've mentioned previously, recursively listing versioned directory trees, reporting which paths were modified in a given revision or transaction, showing textual and property differences made to files and directories, and so on. See <xref linkend=\"svn.ref.svnlook\"/> for a full reference of <command>svnlook</command>'s features."
7235 #: ../source/book.xml:10057
7236 msgid "While it won't be the most commonly used tool at the administrator's disposal, <command>svndumpfilter</command> provides a very particular brand of useful functionality—the ability to quickly and easily modify streams of Subversion repository history data by acting as a path-based filter."
7240 #: ../source/book.xml:10063
7241 msgid "The syntax of <command>svndumpfilter</command> is as follows:"
7245 #: ../source/book.xml:10065
7247 msgid "\n$ svndumpfilter help\ngeneral usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS ...]\nType \"svndumpfilter help <subcommand>\" for help on a specific subcommand.\nType 'svndumpfilter --version' to see the program version.\n \nAvailable subcommands:\n exclude\n include\n help (?, h)\n"
7251 #: ../source/book.xml:10076
7252 msgid "There are only two interesting subcommands. They allow you to make the choice between explicit or implicit inclusion of paths in the stream:"
7256 #: ../source/book.xml:10082
7261 #: ../source/book.xml:10085
7262 msgid "Filter out a set of paths from the dump data stream."
7266 #: ../source/book.xml:10091
7271 #: ../source/book.xml:10094
7272 msgid "Allow only the requested set of paths to pass through the dump data stream."
7276 #: ../source/book.xml:10099
7277 msgid "You can learn more about these subcommands and <command>svndumpfilter</command>'s unique purpose in <xref linkend=\"svn.reposadmin.maint.filtering\"/>."
7281 #: ../source/book.xml:10116
7282 msgid "Or is that, the <quote>sync</quote>?"
7286 #: ../source/book.xml:10107
7287 msgid "The <command>svnsync</command> program, which is new to the 1.4 release of Subversion, provides all the functionality required for maintaining a read-only mirror of a Subversion repository. The program really has one job—to transfer one repository's versioned history into another repository. And while there are few ways to do that, its primary strength is that it can operate remotely—the <quote>source</quote> and <quote>sink</quote><placeholder-1/> repositories may be on different computers from each other and from <command>svnsync</command> itself."
7291 #: ../source/book.xml:10119
7292 msgid "As you might expect, <command>svnsync</command> has a syntax that looks very much like every other program we've mentioned in this chapter:"
7296 #: ../source/book.xml:10122
7298 msgid "\n$ svnsync help\ngeneral usage: svnsync SUBCOMMAND DEST_URL [ARGS & OPTIONS ...]\nType 'svnsync help <subcommand>' for help on a specific subcommand.\nType 'svnsync --version' to see the program version and RA modules.\n\nAvailable subcommands:\n initialize (init)\n synchronize (sync)\n copy-revprops\n help (?, h)\n$\n"
7302 #: ../source/book.xml:10135
7303 msgid "We talk more about replication repositories with <command>svnsync</command> in <xref linkend=\"svn.reposadmin.maint.replication\"/>."
7307 #: ../source/book.xml:10141
7308 msgid "Berkeley DB Utilities"
7312 #: ../source/book.xml:10143
7313 msgid "If you're using a Berkeley DB repository, then all of your versioned filesystem's structure and data live in a set of database tables within the <filename>db/</filename> subdirectory of your repository. This subdirectory is a regular Berkeley DB environment directory, and can therefore be used in conjunction with any of the Berkeley database tools, typically provided as part of the Berkeley DB distribution."
7317 #: ../source/book.xml:10151
7318 msgid "For day-to-day Subversion use, these tools are unnecessary. Most of the functionality typically needed for Subversion repositories has been duplicated in the <command>svnadmin</command> tool. For example, <command>svnadmin list-unused-dblogs</command> and <command>svnadmin list-dblogs</command> perform a subset of what is provided by the Berkeley <command>db_archive</command> command, and <command>svnadmin recover</command> reflects the common use cases of the <command>db_recover</command> utility."
7322 #: ../source/book.xml:10161
7323 msgid "However, there are still a few Berkeley DB utilities that you might find useful. The <command>db_dump</command> and <command>db_load</command> programs write and read, respectively, a custom file format which describes the keys and values in a Berkeley DB database. Since Berkeley databases are not portable across machine architectures, this format is a useful way to transfer those databases from machine to machine, irrespective of architecture or operating system. As we describe later in this chapter, you can also use <command>svnadmin dump</command> and <command>svnadmin load</command> for similar purposes, but <command>db_dump</command> and <command>db_load</command> can do certain jobs just as well and much faster. They can also be useful if the experienced Berkeley DB hacker needs to do in-place tweaking of the data in a BDB-backed repository for some reason, which is something Subversion's utilities won't allow. Also, the <command>db_stat</command> utility can provide useful information about the status of your Berkeley DB environment, including detailed statistics about the locking and storage subsystems."
7327 #: ../source/book.xml:10181
7328 msgid "For more information on the Berkeley DB tool chain, visit the documentation section of the Berkeley DB section of Oracle's website, located at <uri href=\"http://www.oracle.com/technology/documentation/berkeley-db/db/\">http://www.oracle.com/technology/documentation/berkeley-db/db/</uri>."
7332 #: ../source/book.xml:10189
7333 msgid "Commit Log Message Correction"
7337 #: ../source/book.xml:10191
7338 msgid "Sometimes a user will have an error in her log message (a misspelling or some misinformation, perhaps). If the repository is configured (using the <literal>pre-revprop-change</literal> hook; see <xref linkend=\"svn.reposadmin.create.hooks\"/>) to accept changes to this log message after the commit is finished, then the user can <quote>fix</quote> her log message remotely using the <command>svn</command> program's <literal>propset</literal> command (see <xref linkend=\"svn.ref.svn.c.propset\"/>). However, because of the potential to lose information forever, Subversion repositories are not, by default, configured to allow changes to unversioned properties—except by an administrator."
7342 #: ../source/book.xml:10203
7343 msgid "If a log message needs to be changed by an administrator, this can be done using <command>svnadmin setlog</command>. This command changes the log message (the <literal>svn:log</literal> property) on a given revision of a repository, reading the new value from a provided file."
7347 #: ../source/book.xml:10208
7349 msgid "\n$ echo \"Here is the new, correct log message\" > newlog.txt\n$ svnadmin setlog myrepos newlog.txt -r 388\n"
7353 #: ../source/book.xml:10212
7354 msgid "The <command>svnadmin setlog</command> command, by default, is still bound by the same protections against modifying unversioned properties as a remote client is—the <literal>pre-</literal> and <literal>post-revprop-change</literal> hooks are still triggered, and therefore must be set up to accept changes of this nature. But an administrator can get around these protections by passing the <option>--bypass-hooks</option> option to the <command>svnadmin setlog</command> command."
7358 #: ../source/book.xml:10223
7359 msgid "Remember, though, that by bypassing the hooks, you are likely avoiding such things as email notifications of property changes, backup systems which track unversioned property changes, and so on. In other words, be very careful about what you are changing, and how you change it."
7363 #: ../source/book.xml:10234
7364 msgid "Managing Disk Space"
7368 #: ../source/book.xml:10236
7369 msgid "While the cost of storage has dropped incredibly in the past few years, disk usage is still a valid concern for administrators seeking to version large amounts of data. Every bit of version history information stored in the live repository needs to be backed up elsewhere, perhaps multiple times as part of rotating backup schedules. It is useful to know what pieces of Subversion's repository data need to remain on the live site, which need to be backed up, and which can be safely removed."
7373 #: ../source/book.xml:10248
7374 msgid "How Subversion saves disk space"
7378 #: ../source/book.xml:10250
7379 msgid "To keep the repository small, Subversion uses <firstterm>deltification</firstterm> (or, <quote>deltified storage</quote>) within the repository itself. Deltification involves encoding the representation of a chunk of data as a collection of differences against some other chunk of data. If the two pieces of data are very similar, this deltification results in storage savings for the deltified chunk—rather than taking up space equal to the size of the original data, it takes up only enough space to say, <quote>I look just like this other piece of data over here, except for the following couple of changes</quote>. The result is that most of the repository data that tends to be bulky—namely, the contents of versioned files—is stored at a much smaller size than the original <quote>fulltext</quote> representation of that data. And for repositories created with Subversion 1.4 or later, the space savings are even better—now those fulltext representations of file contents are themselves compressed."
7383 #: ../source/book.xml:10270
7384 msgid "Because all of the data that is subject to deltification in a BDB-backed repository is stored in a single Berkeley DB database file, reducing the size of the stored values will not immediately reduce the size of the database file itself. Berkeley DB will, however, keep internal records of unused areas of the database file, and consume those areas first before growing the size of the database file. So while deltification doesn't produce immediate space savings, it can drastically slow future growth of the database."
7388 #: ../source/book.xml:10285
7389 msgid "Removing dead transactions"
7393 #: ../source/book.xml:10287
7394 msgid "Though they are uncommon, there are circumstances in which a Subversion commit process might fail, leaving behind in the repository the remnants of the revision-to-be that wasn't—an uncommitted transaction and all the file and directory changes associated with it. This could happen for several reasons: perhaps the client operation was inelegantly terminated by the user, or a network failure occurred in the middle of an operation. Regardless of the reason, dead transactions can happen. They don't do any real harm, other than consuming disk space. A fastidious administrator may nonetheless wish to remove them."
7398 #: ../source/book.xml:10299
7399 msgid "You can use <command>svnadmin</command>'s <literal>lstxns</literal> command to list the names of the currently outstanding transactions."
7403 #: ../source/book.xml:10302
7405 msgid "\n$ svnadmin lstxns myrepos\n19\n3a1\na45\n$\n"
7409 #: ../source/book.xml:10309
7410 msgid "Each item in the resultant output can then be used with <command>svnlook</command> (and its <option>--transaction (-t)</option> option) to determine who created the transaction, when it was created, what types of changes were made in the transaction—information that is helpful in determining whether or not the transaction is a safe candidate for removal! If you do indeed want to remove a transaction, its name can be passed to <command>svnadmin rmtxns</command>, which will perform the cleanup of the transaction. In fact, the <literal>rmtxns</literal> subcommand can take its input directly from the output of <literal>lstxns</literal>!"
7414 #: ../source/book.xml:10322
7416 msgid "\n$ svnadmin rmtxns myrepos `svnadmin lstxns myrepos`\n$\n"
7420 #: ../source/book.xml:10326
7421 msgid "If you use these two subcommands like this, you should consider making your repository temporarily inaccessible to clients. That way, no one can begin a legitimate transaction before you start your cleanup. <xref linkend=\"svn.reposadmin.maint.diskspace.deadtxns.ex-1\"/> contains a bit of shell-scripting that can quickly generate information about each outstanding transaction in your repository."
7425 #: ../source/book.xml:10335
7426 msgid "txn-info.sh (Reporting Outstanding Transactions)"
7430 #: ../source/book.xml:10337
7432 msgid "\n#!/bin/sh\n\n### Generate informational output for all outstanding transactions in\n### a Subversion repository.\n\nREPOS=\"${1}\"\nif [ \"x$REPOS\" = x ] ; then\n echo \"usage: $0 REPOS_PATH\"\n exit\nfi\n\nfor TXN in `svnadmin lstxns ${REPOS}`; do \n echo \"---[ Transaction ${TXN} ]-------------------------------------------\"\n svnlook info \"${REPOS}\" -t \"${TXN}\"\ndone\n"
7436 #: ../source/book.xml:10355
7437 msgid "The output of the script is basically a concatenation of several chunks of <command>svnlook info</command> output (see <xref linkend=\"svn.reposadmin.maint.tk.svnlook\"/>), and will look something like:"
7441 #: ../source/book.xml:10359
7443 msgid "\n$ txn-info.sh myrepos\n---[ Transaction 19 ]-------------------------------------------\nsally\n2001-09-04 11:57:19 -0500 (Tue, 04 Sep 2001)\n0\n---[ Transaction 3a1 ]-------------------------------------------\nharry\n2001-09-10 16:50:30 -0500 (Mon, 10 Sep 2001)\n39\nTrying to commit over a faulty network.\n---[ Transaction a45 ]-------------------------------------------\nsally\n2001-09-12 11:09:28 -0500 (Wed, 12 Sep 2001)\n0\n$\n"
7447 #: ../source/book.xml:10376
7448 msgid "A long-abandoned transaction usually represents some sort of failed or interrupted commit. A transaction's datestamp can provide interesting information—for example, how likely is it that an operation begun nine months ago is still active?"
7452 #: ../source/book.xml:10381
7453 msgid "In short, transaction cleanup decisions need not be made unwisely. Various sources of information—including Apache's error and access logs, Subversion's operational logs, Subversion revision history, and so on—can be employed in the decision-making process. And of course, an administrator can often simply communicate with a seemingly dead transaction's owner (via email, for example) to verify that the transaction is, in fact, in a zombie state."
7457 #: ../source/book.xml:10393
7458 msgid "Purging unused Berkeley DB logfiles"
7462 #: ../source/book.xml:10395
7463 msgid "Until recently, the largest offender of disk space usage with respect to BDB-backed Subversion repositories was the log files in which Berkeley DB performs its pre-writes before modifying the actual database files. These files capture all the actions taken along the route of changing the database from one state to another—while the database files, at any given time, reflect a particular state, the log files contain all the many changes along the way <emphasis>between</emphasis> states. Thus, they can grow and accumulate quite rapidly."
7467 #: ../source/book.xml:10405
7468 msgid "Fortunately, beginning with the 4.2 release of Berkeley DB, the database environment has the ability to remove its own unused log files automatically. Any repositories created using an <command>svnadmin</command> which is compiled against Berkeley DB version 4.2 or greater will be configured for this automatic log file removal. If you don't want this feature enabled, simply pass the <option>--bdb-log-keep</option> option to the <command>svnadmin create</command> command. If you forget to do this, or change your mind at a later time, simply edit the <filename>DB_CONFIG</filename> file found in your repository's <filename>db</filename> directory, comment out the line which contains the <literal>set_flags DB_LOG_AUTOREMOVE</literal> directive, and then run <command>svnadmin recover</command> on your repository to force the configuration changes to take effect. See <xref linkend=\"svn.reposadmin.create.bdb\"/> for more information about database configuration."
7472 #: ../source/book.xml:10422
7473 msgid "Without some sort of automatic log file removal in place, log files will accumulate as you use your repository. This is actually somewhat of a feature of the database system—you should be able to recreate your entire database using nothing but the log files, so these files can be useful for catastrophic database recovery. But typically, you'll want to archive the log files that are no longer in use by Berkeley DB, and then remove them from disk to conserve space. Use the <command>svnadmin list-unused-dblogs</command> command to list the unused log files:"
7477 #: ../source/book.xml:10433
7479 msgid "\n$ svnadmin list-unused-dblogs /path/to/repos\n/path/to/repos/log.0000000031\n/path/to/repos/log.0000000032\n/path/to/repos/log.0000000033\n…\n$ rm `svnadmin list-unused-dblogs /path/to/repos`\n## disk space reclaimed!\n"
7483 #: ../source/book.xml:10443
7484 msgid "BDB-backed repositories whose log files are used as part of a backup or disaster recovery plan should <emphasis>not</emphasis> make use of the log file autoremoval feature. Reconstruction of a repository's data from log files can only be accomplished when <emphasis>all</emphasis> the log files are available. If some of the log files are removed from disk before the backup system has a chance to copy them elsewhere, the incomplete set of backed-up log files is essentially useless."
7488 #: ../source/book.xml:10458
7489 msgid "Berkeley DB Recovery"
7493 #: ../source/book.xml:10460
7494 msgid "As mentioned in <xref linkend=\"svn.reposadmin.basics.backends.bdb\"/>, a Berkeley DB repository can sometimes be left in frozen state if not closed properly. When this happens, an administrator needs to rewind the database back into a consistent state. This is unique to BDB-backed repositories, though—if you are using FSFS-backed ones instead, this won't apply to you. And for those of you using Subversion 1.4 with Berkeley DB 4.4 or better, you should find that Subversion has become much more resilient in these types of situations. Still, wedged Berkeley DB repositories do occur, and an administrator needs to know how to safely deal with this circumstance."
7498 #: ../source/book.xml:10471
7499 msgid "In order to protect the data in your repository, Berkeley DB uses a locking mechanism. This mechanism ensures that portions of the database are not simultaneously modified by multiple database accessors, and that each process sees the data in the correct state when that data is being read from the database. When a process needs to change something in the database, it first checks for the existence of a lock on the target data. If the data is not locked, the process locks the data, makes the change it wants to make, and then unlocks the data. Other processes are forced to wait until that lock is removed before they are permitted to continue accessing that section of the database. (This has nothing to do with the locks that you, as a user, can apply to versioned files within the repository; we try to clear up the confusion caused by this terminology collision in <xref linkend=\"svn.advanced.locking.meanings\"/>.)"
7503 #: ../source/book.xml:10486
7504 msgid "In the course of using your Subversion repository, fatal errors or interruptions can prevent a process from having the chance to remove the locks it has placed in the database. The result is that the back-end database system gets <quote>wedged</quote>. When this happens, any attempts to access the repository hang indefinitely (since each new accessor is waiting for a lock to go away—which isn't going to happen)."
7508 #: ../source/book.xml:10498
7509 msgid "E.g.: hard drive + huge electromagnet = disaster."
7513 #: ../source/book.xml:10494
7514 msgid "If this happens to your repository, don't panic. The Berkeley DB filesystem takes advantage of database transactions and checkpoints and pre-write journaling to ensure that only the most catastrophic of events <placeholder-1/> can permanently destroy a database environment. A sufficiently paranoid repository administrator will have made off-site backups of the repository data in some fashion, but don't head off to the tape backup storage closet just yet."
7518 #: ../source/book.xml:10503
7519 msgid "Instead, use the following recipe to attempt to <quote>unwedge</quote> your repository:"
7523 #: ../source/book.xml:10507
7524 msgid "Make sure that there are no processes accessing (or attempting to access) the repository. For networked repositories, this means shutting down the Apache HTTP Server or svnserve daemon, too."
7528 #: ../source/book.xml:10513
7529 msgid "Become the user who owns and manages the repository. This is important, as recovering a repository while running as the wrong user can tweak the permissions of the repository's files in such a way that your repository will still be inaccessible even after it is <quote>unwedged</quote>."
7533 #: ../source/book.xml:10521
7534 msgid "Run the command <command>svnadmin recover /path/to/repos</command>. You should see output like this:"
7538 #: ../source/book.xml:10524
7540 msgid "\nRepository lock acquired.\nPlease wait; recovering the repository may take some time...\n\nRecovery completed.\nThe latest repos revision is 19.\n"
7544 #: ../source/book.xml:10531
7545 msgid "This command may take many minutes to complete."
7549 #: ../source/book.xml:10534
7550 msgid "Restart the server process."
7554 #: ../source/book.xml:10537
7555 msgid "This procedure fixes almost every case of repository lock-up. Make sure that you run this command as the user that owns and manages the database, not just as <literal>root</literal>. Part of the recovery process might involve recreating from scratch various database files (shared memory regions, for example). Recovering as <literal>root</literal> will create those files such that they are owned by <literal>root</literal>, which means that even after you restore connectivity to your repository, regular users will be unable to access it."
7559 #: ../source/book.xml:10547
7560 msgid "If the previous procedure, for some reason, does not successfully unwedge your repository, you should do two things. First, move your broken repository directory aside (perhaps by renaming it to something like <filename>repos.BROKEN</filename>) and then restore your latest backup of it. Then, send an email to the Subversion user list (at <email>users@subversion.tigris.org</email>) describing your problem in detail. Data integrity is an extremely high priority to the Subversion developers."
7564 #: ../source/book.xml:10560
7565 msgid "Migrating Repository Data Elsewhere"
7569 #: ../source/book.xml:10562
7570 msgid "A Subversion filesystem has its data spread throughout files in the repository, in a fashion generally understood by (and of interest to) only the Subversion developers themselves. However, circumstances may arise that call for all, or some subset, of that data to be copied or moved into another repository."
7574 #: ../source/book.xml:10568
7575 msgid "Subversion provides such functionality by way of repository dump streams. A repository dump stream (often referred to as a <quote>dumpfile</quote> when stored as a file on disk) is a portable, flat file format that describes the various revisions in your repository—what was changed, by whom, when, and so on. This dump stream is the primary mechanism used to marshal versioned history—in whole or in part, with or without modification—between repositories. And Subversion provides the tools necessary for creating and loading these dump streams—the <command>svnadmin dump</command> and <command>svnadmin load</command> subcommands, respectively."
7579 #: ../source/book.xml:10581
7580 msgid "While the Subversion repository dump format contains human-readable portions and a familiar structure (it resembles an RFC-822 format, the same type of format used for most email), it is <emphasis>not</emphasis> a plaintext file format. It is a binary file format, highly sensitive to meddling. For example, many text editors will corrupt the file by automatically converting line endings."
7584 #: ../source/book.xml:10589
7585 msgid "There are many reasons for dumping and loading Subversion repository data. Early in Subversion's life, the most common reason was due to the evolution of Subversion itself. As Subversion matured, there were times when changes made to the back-end database schema caused compatibility issues with previous versions of the repository, so users had to dump their repository data using the previous version of Subversion, and load it into a freshly created repository with the new version of Subversion. Now, these types of schema changes haven't occurred since Subversion's 1.0 release, and the Subversion developers promise not to force users to dump and load their repositories when upgrading between minor versions (such as from 1.3 to 1.4) of Subversion. But there are still other reasons for dumping and loading, including re-deploying a Berkeley DB repository on a new OS or CPU architecture, switching between the Berkeley DB and FSFS back-ends, or (as we'll cover in <xref linkend=\"svn.reposadmin.maint.filtering\"/>) purging versioned data from repository history."
7589 #: ../source/book.xml:10607
7590 msgid "Whatever your reason for migrating repository history, using the <command>svnadmin dump</command> and <command>svnadmin load</command> subcommands is straightforward. <command>svnadmin dump</command> will output a range of repository revisions that are formatted using Subversion's custom filesystem dump format. The dump format is printed to the standard output stream, while informative messages are printed to the standard error stream. This allows you to redirect the output stream to a file while watching the status output in your terminal window. For example:"
7594 #: ../source/book.xml:10618
7596 msgid "\n$ svnlook youngest myrepos\n26\n$ svnadmin dump myrepos > dumpfile\n* Dumped revision 0.\n* Dumped revision 1.\n* Dumped revision 2.\n…\n* Dumped revision 25.\n* Dumped revision 26.\n"
7600 #: ../source/book.xml:10629
7601 msgid "At the end of the process, you will have a single file (<filename>dumpfile</filename> in the previous example) that contains all the data stored in your repository in the requested range of revisions. Note that <command>svnadmin dump</command> is reading revision trees from the repository just like any other <quote>reader</quote> process would (<command>svn checkout</command>, for example), so it's safe to run this command at any time."
7605 #: ../source/book.xml:10637
7606 msgid "The other subcommand in the pair, <command>svnadmin load</command>, parses the standard input stream as a Subversion repository dump file, and effectively replays those dumped revisions into the target repository for that operation. It also gives informative feedback, this time using the standard output stream:"
7610 #: ../source/book.xml:10643
7612 msgid "\n$ svnadmin load newrepos < dumpfile\n<<< Started new txn, based on original revision 1\n * adding path : A ... done.\n * adding path : A/B ... done.\n …\n------- Committed new rev 1 (loaded from original rev 1) >>>\n\n<<< Started new txn, based on original revision 2\n * editing path : A/mu ... done.\n * editing path : A/D/G/rho ... done.\n\n------- Committed new rev 2 (loaded from original rev 2) >>>\n\n…\n\n<<< Started new txn, based on original revision 25\n * editing path : A/D/gamma ... done.\n\n------- Committed new rev 25 (loaded from original rev 25) >>>\n\n<<< Started new txn, based on original revision 26\n * adding path : A/Z/zeta ... done.\n * editing path : A/mu ... done.\n\n------- Committed new rev 26 (loaded from original rev 26) >>>\n\n"
7616 #: ../source/book.xml:10671
7617 msgid "The result of a load is new revisions added to a repository—the same thing you get by making commits against that repository from a regular Subversion client. And just as in a commit, you can use hook programs to perform actions before and after each of the commits made during a load process. By passing the <option>--use-pre-commit-hook</option> and <option>--use-post-commit-hook</option> options to <command>svnadmin load</command>, you can instruct Subversion to execute the pre-commit and post-commit hook programs, respectively, for each loaded revision. You might use these, for example, to ensure that loaded revisions pass through the same validation steps that regular commits pass through. Of course, you should use these options with care—if your post-commit hook sends emails to a mailing list for each new commit, you might not want to spew hundreds or thousands of commit emails in rapid succession at that list! You can read more about the use of hook scripts in <xref linkend=\"svn.reposadmin.create.hooks\"/>."
7621 #: ../source/book.xml:10689
7622 msgid "Note that because <command>svnadmin</command> uses standard input and output streams for the repository dump and load process, people who are feeling especially saucy can try things like this (perhaps even using different versions of <command>svnadmin</command> on each side of the pipe):"
7626 #: ../source/book.xml:10694
7628 msgid "\n$ svnadmin create newrepos\n$ svnadmin dump oldrepos | svnadmin load newrepos\n"
7632 #: ../source/book.xml:10698
7633 msgid "By default, the dump file will be quite large—much larger than the repository itself. That's because by default every version of every file is expressed as a full text in the dump file. This is the fastest and simplest behavior, and nice if you're piping the dump data directly into some other process (such as a compression program, filtering program, or into a loading process). But if you're creating a dump file for longer-term storage, you'll likely want to save disk space by using the <option>--deltas</option> option. With this option, successive revisions of files will be output as compressed, binary differences—just as file revisions are stored in a repository. This option is slower, but results in a dump file much closer in size to the original repository."
7637 #: ../source/book.xml:10712
7638 msgid "We mentioned previously that <command>svnadmin dump</command> outputs a range of revisions. Use the <option>--revision (-r)</option> option to specify a single revision to dump, or a range of revisions. If you omit this option, all the existing repository revisions will be dumped."
7642 #: ../source/book.xml:10718
7644 msgid "\n$ svnadmin dump myrepos -r 23 > rev-23.dumpfile\n$ svnadmin dump myrepos -r 100:200 > revs-100-200.dumpfile\n"
7648 #: ../source/book.xml:10722
7649 msgid "As Subversion dumps each new revision, it outputs only enough information to allow a future loader to re-create that revision based on the previous one. In other words, for any given revision in the dump file, only the items that were changed in that revision will appear in the dump. The only exception to this rule is the first revision that is dumped with the current <command>svnadmin dump</command> command."
7653 #: ../source/book.xml:10730
7654 msgid "By default, Subversion will not express the first dumped revision as merely differences to be applied to the previous revision. For one thing, there is no previous revision in the dump file! And secondly, Subversion cannot know the state of the repository into which the dump data will be loaded (if it ever is). To ensure that the output of each execution of <command>svnadmin dump</command> is self-sufficient, the first dumped revision is by default a full representation of every directory, file, and property in that revision of the repository."
7658 #: ../source/book.xml:10740
7659 msgid "However, you can change this default behavior. If you add the <option>--incremental</option> option when you dump your repository, <command>svnadmin</command> will compare the first dumped revision against the previous revision in the repository, the same way it treats every other revision that gets dumped. It will then output the first revision exactly as it does the rest of the revisions in the dump range—mentioning only the changes that occurred in that revision. The benefit of this is that you can create several small dump files that can be loaded in succession, instead of one large one, like so:"
7663 #: ../source/book.xml:10751
7665 msgid "\n$ svnadmin dump myrepos -r 0:1000 > dumpfile1\n$ svnadmin dump myrepos -r 1001:2000 --incremental > dumpfile2\n$ svnadmin dump myrepos -r 2001:3000 --incremental > dumpfile3\n"
7669 #: ../source/book.xml:10756
7670 msgid "These dump files could be loaded into a new repository with the following command sequence:"
7674 #: ../source/book.xml:10758
7676 msgid "\n$ svnadmin load newrepos < dumpfile1\n$ svnadmin load newrepos < dumpfile2\n$ svnadmin load newrepos < dumpfile3\n"
7680 #: ../source/book.xml:10763
7681 msgid "Another neat trick you can perform with this <option>--incremental</option> option involves appending to an existing dump file a new range of dumped revisions. For example, you might have a <literal>post-commit</literal> hook that simply appends the repository dump of the single revision that triggered the hook. Or you might have a script that runs nightly to append dump file data for all the revisions that were added to the repository since the last time the script ran. Used like this, <command>svnadmin dump</command> can be one way to back up changes to your repository over time in case of a system crash or some other catastrophic event."
7685 #: ../source/book.xml:10774
7686 msgid "The dump format can also be used to merge the contents of several different repositories into a single repository. By using the <option>--parent-dir</option> option of <command>svnadmin load</command>, you can specify a new virtual root directory for the load process. That means if you have dump files for three repositories, say <filename>calc-dumpfile</filename>, <filename>cal-dumpfile</filename>, and <filename>ss-dumpfile</filename>, you can first create a new repository to hold them all:"
7690 #: ../source/book.xml:10784
7692 msgid "\n$ svnadmin create /path/to/projects\n$\n"
7696 #: ../source/book.xml:10788
7697 msgid "Then, make new directories in the repository which will encapsulate the contents of each of the three previous repositories:"
7701 #: ../source/book.xml:10791
7703 msgid "\n$ svn mkdir -m \"Initial project roots\" \\\n file:///path/to/projects/calc \\\n file:///path/to/projects/calendar \\\n file:///path/to/projects/spreadsheet\nCommitted revision 1.\n$ \n"
7707 #: ../source/book.xml:10799
7708 msgid "Lastly, load the individual dump files into their respective locations in the new repository:"
7712 #: ../source/book.xml:10801
7714 msgid "\n$ svnadmin load /path/to/projects --parent-dir calc < calc-dumpfile\n…\n$ svnadmin load /path/to/projects --parent-dir calendar < cal-dumpfile\n…\n$ svnadmin load /path/to/projects --parent-dir spreadsheet < ss-dumpfile\n…\n$\n"
7718 #: ../source/book.xml:10810
7719 msgid "We'll mention one final way to use the Subversion repository dump format—conversion from a different storage mechanism or version control system altogether. Because the dump file format is, for the most part, human-readable, it should be relatively easy to describe generic sets of changes—each of which should be treated as a new revision—using this file format. In fact, the <command>cvs2svn</command> utility (see <xref linkend=\"svn.forcvs.convert\"/>) uses the dump format to represent the contents of a CVS repository so that those contents can be copied into a Subversion repository."
7723 #: ../source/book.xml:10824
7724 msgid "Filtering Repository History"
7728 #: ../source/book.xml:10833
7729 msgid "That's rather the reason you use version control at all, right?"
7733 #: ../source/book.xml:10840
7734 msgid "Conscious, cautious removal of certain bits of versioned data is actually supported by real use-cases. That's why an <quote>obliterate</quote> feature has been one of the most highly requested Subversion features, and one which the Subversion developers hope to soon provide."
7738 #: ../source/book.xml:10826
7739 msgid "Since Subversion stores your versioned history using, at the very least, binary differencing algorithms and data compression (optionally in a completely opaque database system), attempting manual tweaks is unwise, if not quite difficult, and at any rate strongly discouraged. And once data has been stored in your repository, Subversion generally doesn't provide an easy way to remove that data. <placeholder-1/> But inevitably, there will be times when you would like to manipulate the history of your repository. You might need to strip out all instances of a file that was accidentally added to the repository (and shouldn't be there for whatever reason). <placeholder-2/> Or, perhaps you have multiple projects sharing a single repository, and you decide to split them up into their own repositories. To accomplish tasks like this, administrators need a more manageable and malleable representation of the data in their repositories—the Subversion repository dump format."
7743 #: ../source/book.xml:10852
7744 msgid "As we described in <xref linkend=\"svn.reposadmin.maint.migrate\"/>, the Subversion repository dump format is a human-readable representation of the changes that you've made to your versioned data over time. You use the <command>svnadmin dump</command> command to generate the dump data, and <command>svnadmin load</command> to populate a new repository with it (see <xref linkend=\"svn.reposadmin.maint.migrate\"/>). The great thing about the human-readability aspect of the dump format is that, if you aren't careless about it, you can manually inspect and modify it. Of course, the downside is that if you have three years' worth of repository activity encapsulated in what is likely to be a very large dump file, it could take you a long, long time to manually inspect and modify it."
7748 #: ../source/book.xml:10866
7749 msgid "That's where <command>svndumpfilter</command> becomes useful. This program acts as path-based filter for repository dump streams. Simply give it either a list of paths you wish to keep, or a list of paths you wish to not keep, then pipe your repository dump data through this filter. The result will be a modified stream of dump data that contains only the versioned paths you (explicitly or implicitly) requested."
7753 #: ../source/book.xml:10874
7754 msgid "Let's look a realistic example of how you might use this program. We discuss elsewhere (see <xref linkend=\"svn.reposadmin.projects.chooselayout\"/>) the process of deciding how to choose a layout for the data in your repositories—using one repository per project or combining them, arranging stuff within your repository, and so on. But sometimes after new revisions start flying in, you rethink your layout and would like to make some changes. A common change is the decision to move multiple projects which are sharing a single repository into separate repositories for each project."
7758 #: ../source/book.xml:10884
7759 msgid "Our imaginary repository contains three projects: <literal>calc</literal>, <literal>calendar</literal>, and <literal>spreadsheet</literal>. They have been living side-by-side in a layout like this:"
7763 #: ../source/book.xml:10888
7765 msgid "\n/\n calc/\n trunk/\n branches/\n tags/\n calendar/\n trunk/\n branches/\n tags/\n spreadsheet/\n trunk/\n branches/\n tags/\n"
7769 #: ../source/book.xml:10903
7770 msgid "To get these three projects into their own repositories, we first dump the whole repository:"
7774 #: ../source/book.xml:10905
7776 msgid "\n$ svnadmin dump /path/to/repos > repos-dumpfile\n* Dumped revision 0.\n* Dumped revision 1.\n* Dumped revision 2.\n* Dumped revision 3.\n…\n$\n"
7780 #: ../source/book.xml:10914
7781 msgid "Next, run that dump file through the filter, each time including only one of our top-level directories, and resulting in three new dump files:"
7785 #: ../source/book.xml:10917
7787 msgid "\n$ svndumpfilter include calc < repos-dumpfile > calc-dumpfile\n…\n$ svndumpfilter include calendar < repos-dumpfile > cal-dumpfile\n…\n$ svndumpfilter include spreadsheet < repos-dumpfile > ss-dumpfile\n…\n$\n"
7791 #: ../source/book.xml:10926
7792 msgid "At this point, you have to make a decision. Each of your dump files will create a valid repository, but will preserve the paths exactly as they were in the original repository. This means that even though you would have a repository solely for your <literal>calc</literal> project, that repository would still have a top-level directory named <filename>calc</filename>. If you want your <filename>trunk</filename>, <filename>tags</filename>, and <filename>branches</filename> directories to live in the root of your repository, you might wish to edit your dump files, tweaking the <literal>Node-path</literal> and <literal>Node-copyfrom-path</literal> headers to no longer have that first <filename>calc/</filename> path component. Also, you'll want to remove the section of dump data that creates the <filename>calc</filename> directory. It will look something like:"
7796 #: ../source/book.xml:10942
7798 msgid "\nNode-path: calc\nNode-action: add\nNode-kind: dir\nContent-length: 0\n \n"
7802 #: ../source/book.xml:10950
7803 msgid "If you do plan on manually editing the dump file to remove a top-level directory, make sure that your editor is not set to automatically convert end-of-line characters to the native format (e.g. \\r\\n to \\n), as the content will then not agree with the metadata. This will render the dump file useless."
7807 #: ../source/book.xml:10957
7808 msgid "All that remains now is to create your three new repositories, and load each dump file into the right repository:"
7812 #: ../source/book.xml:10960
7814 msgid "\n$ svnadmin create calc; svnadmin load calc < calc-dumpfile\n<<< Started new transaction, based on original revision 1\n * adding path : Makefile ... done.\n * adding path : button.c ... done.\n…\n$ svnadmin create calendar; svnadmin load calendar < cal-dumpfile\n<<< Started new transaction, based on original revision 1\n * adding path : Makefile ... done.\n * adding path : cal.c ... done.\n…\n$ svnadmin create spreadsheet; svnadmin load spreadsheet < ss-dumpfile\n<<< Started new transaction, based on original revision 1\n * adding path : Makefile ... done.\n * adding path : ss.c ... done.\n…\n$\n"
7818 #: ../source/book.xml:10978
7819 msgid "Both of <command>svndumpfilter</command>'s subcommands accept options for deciding how to deal with <quote>empty</quote> revisions. If a given revision contained only changes to paths that were filtered out, that now-empty revision could be considered uninteresting or even unwanted. So to give the user control over what to do with those revisions, <command>svndumpfilter</command> provides the following command-line options:"
7823 #: ../source/book.xml:10989
7824 msgid "--drop-empty-revs"
7828 #: ../source/book.xml:10992
7829 msgid "Do not generate empty revisions at all—just omit them."
7833 #: ../source/book.xml:10998
7834 msgid "--renumber-revs"
7838 #: ../source/book.xml:11001
7839 msgid "If empty revisions are dropped (using the <option>--drop-empty-revs</option> option), change the revision numbers of the remaining revisions so that there are no gaps in the numeric sequence."
7843 #: ../source/book.xml:11009
7844 msgid "--preserve-revprops"
7848 #: ../source/book.xml:11012
7849 msgid "If empty revisions are not dropped, preserve the revision properties (log message, author, date, custom properties, etc.) for those empty revisions. Otherwise, empty revisions will only contain the original datestamp, and a generated log message that indicates that this revision was emptied by <command>svndumpfilter</command>."
7853 #: ../source/book.xml:11022
7854 msgid "While <command>svndumpfilter</command> can be very useful, and a huge timesaver, there are unfortunately a couple of gotchas. First, this utility is overly sensitive to path semantics. Pay attention to whether paths in your dump file are specified with or without leading slashes. You'll want to look at the <literal>Node-path</literal> and <literal>Node-copyfrom-path</literal> headers."
7858 #: ../source/book.xml:11029
7860 msgid "\n…\nNode-path: spreadsheet/Makefile\n…\n"
7864 #: ../source/book.xml:11040
7865 msgid "While <command>svnadmin dump</command> has a consistent leading slash policy—to not include them—other programs which generate dump data might not be so consistent."
7869 #: ../source/book.xml:11034
7870 msgid "If the paths have leading slashes, you should include leading slashes in the paths you pass to <command>svndumpfilter include</command> and <command>svndumpfilter exclude</command> (and if they don't, you shouldn't). Further, if your dump file has an inconsistent usage of leading slashes for some reason, <placeholder-1/> you should probably normalize those paths so they all have, or lack, leading slashes."
7874 #: ../source/book.xml:11046
7875 msgid "Also, copied paths can give you some trouble. Subversion supports copy operations in the repository, where a new path is created by copying some already existing path. It is possible that at some point in the lifetime of your repository, you might have copied a file or directory from some location that <command>svndumpfilter</command> is excluding, to a location that it is including. In order to make the dump data self-sufficient, <command>svndumpfilter</command> needs to still show the addition of the new path—including the contents of any files created by the copy—and not represent that addition as a copy from a source that won't exist in your filtered dump data stream. But because the Subversion repository dump format only shows what was changed in each revision, the contents of the copy source might not be readily available. If you suspect that you have any copies of this sort in your repository, you might want to rethink your set of included/excluded paths, perhaps including the paths that served as sources of your troublesome copy operations, too."
7879 #: ../source/book.xml:11066
7880 msgid "Finally, <command>svndumpfilter</command> takes path filtering quite literally. If you are trying to copy the history of a project rooted at <filename>trunk/my-project</filename> and move it into a repository of its own, you would, of course, use the <command>svndumpfilter include</command> command to keep all the changes in and under <filename>trunk/my-project</filename>. But the resulting dump file makes no assumptions about the repository into which you plan to load this data. Specifically, the dump data might begin with the revision which added the <filename>trunk/my-project</filename> directory, but it will <emphasis>not</emphasis> contain directives which would create the <filename>trunk</filename> directory itself (because <filename>trunk</filename> doesn't match the include filter). You'll need to make sure that any directories which the new dump stream expect to exist actually do exist in the target repository before trying to load the stream into that repository."
7884 #: ../source/book.xml:11089
7885 msgid "Repository Replication"
7889 #: ../source/book.xml:11091
7890 msgid "There are several scenarios in which it is quite handy to have a Subversion repository whose version history is exactly the same as some other repository's. Perhaps the most obvious one is the maintenance of a simple backup repository, used when the primary repository has become inaccessible due to a hardware failure, network outage, or other such annoyance. Other scenarios include deploying mirror repositories to distribute heavy Subversion load across multiple servers, use as a soft-upgrade mechanism, and so on."
7894 #: ../source/book.xml:11100
7895 msgid "As of version 1.4, Subversion provides a program for managing scenarios like these—<command>svnsync</command>. <command>svnsync</command> works by essentially asking the Subversion server to <quote>replay</quote> revisions, one at a time. It then uses that revision information to mimic a commit of the same to another repository. Neither repository needs to be locally accessible to machine on which <command>svnsync</command> is running—its parameters are repository URLs, and it does all its work through Subversion's repository access (RA) interfaces. All it requires is read access to the source repository and read/write access to the destination repository."
7899 #: ../source/book.xml:11114
7900 msgid "When using <command>svnsync</command> against a remote source repository, the Subversion server for that repository must be running Subversion version 1.4 or better."
7904 #: ../source/book.xml:11130
7905 msgid "In fact, it can't truly be read-only, or <command>svnsync</command> itself would have a tough time copying revision history into it."
7909 #: ../source/book.xml:11118
7910 msgid "Assuming you already have a source repository that you'd like to mirror, the next thing you need is an empty target repository which will actually serve as that mirror. This target repository can use either of the available filesystem data-store back-ends (see <xref linkend=\"svn.reposadmin.basics.backends\"/>), but it must not yet have any version history in it. The protocol via which <command>svnsync</command> communicates revision information is highly sensitive to mismatches between the versioned histories contained in the source and target repositories. For this reason, while <command>svnsync</command> cannot <emphasis>demand</emphasis> that the target repository be read-only, <placeholder-1/> allowing the revision history in the target repository to change by any mechanism other than the mirroring process is a recipe for disaster."
7914 #: ../source/book.xml:11137
7915 msgid "Do <emphasis>not</emphasis> modify a mirror repository in such a way as to cause its version history to deviate from that of the repository it mirrors. The only commits and revision property modifications that ever occur on that mirror repository should be those performed by the <command>svnsync</command> tool."
7919 #: ../source/book.xml:11144
7920 msgid "Another requirement of the target repository is that the <command>svnsync</command> process be allowed to modify certain revision properties. <command>svnsync</command> stores its bookkeeping information in special revision properties on revision 0 of the destination repository. Because <command>svnsync</command> works within the framework of that repository's hook system, the default state of the repository (which is to disallow revision property changes; see <xref linkend=\"svn.ref.reposhooks.pre-revprop-change\"/>) is insufficient. You'll need to explicitly implement the pre-revprop-change hook, and your script must allow <command>svnsync</command> to set and change its special properties. With those provisions in place, you are ready to start mirroring repository revisions."
7924 #: ../source/book.xml:11159
7925 msgid "It's a good idea to implement authorization measures which allow your repository replication process to perform its tasks while preventing other users from modifying the contents of your mirror repository at all."
7929 #: ../source/book.xml:11164
7930 msgid "Let's walk through the use of <command>svnsync</command> in a somewhat typical mirroring scenario. We'll pepper this discourse with practical recommendations which you are free to disregard if they aren't required by or suitable for your environment."
7934 #: ../source/book.xml:11169
7935 msgid "As a service to the fine developers of our favorite version control system, we will be mirroring the public Subversion source code repository and exposing that mirror publicly on the Internet, hosted on a different machine than the one on which the original Subversion source code repository lives. This remote host has a global configuration which permits anonymous users to read the contents of repositories on the host, but requires users to authenticate in order to modify those repositories. (Please forgive us for glossing over the details of Subversion server configuration for the moment—those are covered thoroughly in <xref linkend=\"svn.serverconfig\"/>.) And for no other reason than that it makes for a more interesting example, we'll be driving the replication process from a third machine, the one which we currently find ourselves using."
7939 #: ../source/book.xml:11183
7940 msgid "First, we'll create the repository which will be our mirror. This and the next couple of steps do require shell access to the machine on which the mirror repository will live. Once the repository is all configured, though, we shouldn't need to touch it directly again."
7944 #: ../source/book.xml:11188
7946 msgid "\n$ ssh admin@svn.example.com \\\n \"svnadmin create /path/to/repositories/svn-mirror\"\nadmin@svn.example.com's password: ********\n$\n"
7950 #: ../source/book.xml:11194
7951 msgid "At this point, we have our repository, and due to our server's configuration, that repository is now <quote>live</quote> on the Internet. Now, because we don't want anything modifying the repository except our replication process, we need a way to distinguish that process from other would-be committers. To do so, we use a dedicated username for our process. Only commits and revision property modifications performed by the special username <literal>syncuser</literal> will be allowed."
7955 #: ../source/book.xml:11203
7956 msgid "We'll use the repository's hook system both to allow the replication process to do what it needs to do, and to enforce that only it is doing those things. We accomplish this by implementing two of the repository event hooks—pre-revprop-change and start-commit. Our <filename>pre-revprop-change</filename> hook script is found in <xref linkend=\"svn.reposadmin.maint.replication.pre-revprop-change\"/>, and basically verifies that the user attempting the property changes is our <literal>syncuser</literal> user. If so, the change is allowed; otherwise, it is denied."
7960 #: ../source/book.xml:11214
7961 msgid "Mirror repository's pre-revprop-change hook script"
7965 #: ../source/book.xml:11216
7967 msgid "\n#!/bin/sh \n\nUSER=\"$3\"\n\nif [ \"$USER\" = \"syncuser\" ]; then exit 0; fi\n\necho \"Only the syncuser user may change revision properties\" >&2\nexit 1\n"
7971 #: ../source/book.xml:11227
7972 msgid "That covers revision property changes. Now we need to ensure that only the <literal>syncuser</literal> user is permitted to commit new revisions to the repository. We do this using a <filename>start-commit</filename> hook scripts like the one in <xref linkend=\"svn.reposadmin.maint.replication.start-commit\"/>."
7976 #: ../source/book.xml:11234
7977 msgid "Mirror repository's start-commit hook script"
7981 #: ../source/book.xml:11236
7983 msgid "\n#!/bin/sh \n\nUSER=\"$2\"\n\nif [ \"$USER\" = \"syncuser\" ]; then exit 0; fi\n\necho \"Only the syncuser user may commit new revisions\" >&2\nexit 1\n"
7987 #: ../source/book.xml:11247
7988 msgid "After installing our hook scripts and ensuring that they are executable by the Subversion server, we're finished with the setup of the mirror repository. Now, we get to actually do the mirroring."
7992 #: ../source/book.xml:11251
7993 msgid "The first thing we need to do with <command>svnsync</command> is to register in our target repository the fact that it will be a mirror of the source repository. We do this using the <command>svnsync initialize</command> subcommand. Note that the various <command>svnsync</command> subcommands provide several of the same authentication-related options that <command>svn</command> does: <option>--username</option>, <option>--password</option>, <option>--non-interactive</option>, <option>--config-dir</option>, and <option>--no-auth-cache</option>."
7997 #: ../source/book.xml:11263
7999 msgid "\n$ svnsync help init\ninitialize (init): usage: svnsync initialize DEST_URL SOURCE_URL\n\nInitialize a destination repository for synchronization from\nanother repository.\n\nThe destination URL must point to the root of a repository with\nno committed revisions. The destination repository must allow\nrevision property changes.\n\nYou should not commit to, or make revision property changes in,\nthe destination repository by any method other than 'svnsync'.\nIn other words, the destination repository should be a read-only\nmirror of the source repository.\n\nValid options:\n --non-interactive : do no interactive prompting\n --no-auth-cache : do not cache authentication tokens\n --username arg : specify a username ARG\n --password arg : specify a password ARG\n --config-dir arg : read user configuration files from directory ARG\n\n$ svnsync initialize http://svn.example.com/svn-mirror \\\n http://svn.collab.net/repos/svn \\\n --username syncuser --password syncpass\nCopied properties for revision 0.\n$\n"
8003 #: ../source/book.xml:11292
8004 msgid "Our target repository will now remember that it is a mirror of the public Subversion source code repository. Notice that we provided a username and password as arguments to <command>svnsync</command>—that was required by the pre-revprop-change hook on our mirror repository."
8008 #: ../source/book.xml:11298
8009 msgid "The URLs provided to <command>svnsync</command> must point to the root directories of the target and source repositories, respectively. The tool does not handle mirroring of repository subtrees."
8013 #: ../source/book.xml:11304
8014 msgid "The initial release of <command>svnsync</command> (in Subversion 1.4) has a small shortcoming—the values given to the <option>--username</option> and <option>--password</option> command-line options get used for authentication against both the source and destination repositories. Obviously, there's no guarantee that the synchronizing user's credentials are the same in both places. In the event that they are not the same, users trying to run <command>svnsync</command> in non-interactive mode (with the <option>--non-interactive</option> option) might experience problems."
8018 #: ../source/book.xml:11320
8019 msgid "Be forewarned that while it will take only a few seconds for the average reader to parse this paragraph and the sample output which follows it, the actual time required to complete such a mirroring operation is, shall we say, quite a bit longer."
8023 #: ../source/book.xml:11316
8024 msgid "And now comes the fun part. With a single subcommand, we can tell <command>svnsync</command> to copy all the as-yet-unmirrored revisions from the source repository to the target. <placeholder-1/> The <command>svnsync synchronize</command> subcommand will peek into the special revision properties previously stored on the target repository, and determine what repository it is mirroring and that the most recently mirrored revision was revision 0. Then it will query the source repository and determine what the latest revision in that repository is. Finally, it asks the source repository's server to start replaying all the revisions between 0 and that latest revision. As <command>svnsync</command> get the resulting response from the source repository's server, it begins forwarding those revisions to the target repository's server as new commits."
8028 #: ../source/book.xml:11337
8030 msgid "\n$ svnsync help synchronize\nsynchronize (sync): usage: svnsync synchronize DEST_URL\n\nTransfer all pending revisions from source to destination.\n…\n$ svnsync synchronize http://svn.example.com/svn-mirror \\\n --username syncuser --password syncpass\nCommitted revision 1.\nCopied properties for revision 1.\nCommitted revision 2.\nCopied properties for revision 2.\nCommitted revision 3.\nCopied properties for revision 3.\n…\nCommitted revision 23406.\nCopied properties for revision 23406.\nCommitted revision 23407.\nCopied properties for revision 23407.\nCommitted revision 23408.\nCopied properties for revision 23408.\n"
8034 #: ../source/book.xml:11359
8035 msgid "Of particular interest here is that for each mirrored revision, there is first a commit of that revision to the target repository, and then property changes follow. This is because the initial commit is performed by (and attributed to) the user <literal>syncuser</literal>, and datestamped with the time as of that revision's creation. Also, Subversion's underlying repository access interfaces don't provide a mechanism for setting arbitrary revision properties as part of a commit. So <command>svnsync</command> follows up with an immediate series of property modifications which copy all the revision properties found for that revision in the source repository into the target repository. This also has the effect of fixing the author and datestamp of the revision to match that of the source repository."
8039 #: ../source/book.xml:11373
8040 msgid "Also noteworthy is that <command>svnsync</command> performs careful bookkeeping that allows it to be safely interrupted and restarted without ruining the integrity of the mirrored data. If a network glitch occurs while mirroring a repository, simply repeat the <command>svnsync synchronize</command> command and it will happily pick up right where it left off. In fact, as new revisions appear in the source repository, this is exactly what you to do in order to keep your mirror up-to-date."
8044 #: ../source/book.xml:11382
8045 msgid "There is, however, one bit of inelegance in the process. Because Subversion revision properties can be changed at any time throughout the lifetime of the repository, and don't leave an audit trail that indicates when they were changed, replication processes have to pay special attention to them. If you've already mirrored the first 15 revisions of a repository and someone then changes a revision property on revision 12, <command>svnsync</command> won't know to go back and patch up its copy of revision 12. You'll need to tell it to do so manually by using (or with some additionally tooling around) the <command>svnsync copy-revprops</command> subcommand, which simply re-replicates all the revision properties for a particular revision."
8049 #: ../source/book.xml:11395
8051 msgid "\n$ svnsync help copy-revprops\ncopy-revprops: usage: svnsync copy-revprops DEST_URL REV\n\nCopy all revision properties for revision REV from source to\ndestination.\n…\n$ svnsync copy-revprops http://svn.example.com/svn-mirror 12 \\\n --username syncuser --password syncpass\nCopied properties for revision 12.\n$\n"
8055 #: ../source/book.xml:11407
8056 msgid "That's repository replication in a nutshell. You'll likely want some automation around such a process. For example, while our example was a pull-and-push setup, you might wish to have your primary repository push changes to one or more blessed mirrors as part of its post-commit and post-revprop-change hook implementations. This would enable the mirror to be up-to-date in as near to realtime as is likely possible."
8060 #: ../source/book.xml:11415
8061 msgid "Also, while it isn't very commonplace to do so, <command>svnsync</command> does gracefully mirror repositories in which the user as whom it authenticates only has partial read access. It simply copies only the bits of the repository that it is permitted to see. Obviously such a mirror is not useful as a backup solution."
8065 #: ../source/book.xml:11421
8066 msgid "As far as user interaction with repositories and mirrors goes, it <emphasis>is</emphasis> possible to have a single working copy that interacts with both, but you'll have to jump through some hoops to make it happen. First, you need to ensure that both the primary and mirror repositories have the same repository UUID (which is not the case by default). You can set the mirror repository's UUID by loading a dump file stub into it which contains the UUID of the primary repository, like so:"
8070 #: ../source/book.xml:11430
8072 msgid "\n$ cat - <<EOF | svnadmin load --force-uuid dest\nSVN-fs-dump-format-version: 2\n\nUUID: 65390229-12b7-0310-b90b-f21a5aa7ec8e\nEOF\n$\n"
8076 #: ../source/book.xml:11438
8077 msgid "Now that the two repositories have the same UUID, you can use <command>svn switch --relocate</command> to point your working copy to whichever of the repositories you wish to operate against, a process which is described in <xref linkend=\"svn.ref.svn.c.switch\"/>. There is a possible danger here, though, in that if the primary and mirror repositories aren't in close synchronization, a working copy up-to-date with, and pointing to, the primary repository will, if relocated to point to an out-of-date mirror, become confused about the apparent sudden loss of revisions it fully expects to be present, and throws errors to that effect. If this occurs, you can relocate your working copy back to the primary repository and then either wait until the mirror repository is up-to-date, or backdate your working copy to a revision you know is present in the sync repository and then retry the relocation."
8081 #: ../source/book.xml:11453
8082 msgid "Finally, be aware that the revision-based replication provided by <command>svnsync</command> is only that—replication of revisions. It does not include such things as the hook implementations, repository or server configuration data, uncommitted transactions, or information about user locks on repository paths. Only information carried by the Subversion repository dump file format is available for replication."
8086 #: ../source/book.xml:11465
8087 msgid "Repository Backup"
8091 #: ../source/book.xml:11467
8092 msgid "Despite numerous advances in technology since the birth of the modern computer, one thing unfortunately rings true with crystalline clarity—sometimes, things go very, very awry. Power outages, network connectivity dropouts, corrupt RAM and crashed hard drives are but a taste of the evil that Fate is poised to unleash on even the most conscientious administrator. And so we arrive at a very important topic—how to make backup copies of your repository data."
8096 #: ../source/book.xml:11476
8097 msgid "There are two types of backup methods available for Subversion repository administrators—full and incremental. A full backup of the repository involves squirreling away in one sweeping action all the information required to fully reconstruct that repository in the event of a catastrophe. Usually, it means, quite literally, the duplication of the entire repository directory (which includes either a Berkeley DB or FSFS environment). Incremental backups are lesser things, backups of only the portion of the repository data that has changed since the previous backup."
8101 #: ../source/book.xml:11487
8102 msgid "As far as full backups go, the naive approach might seem like a sane one, but unless you temporarily disable all other access to your repository, simply doing a recursive directory copy runs the risk of generating a faulty backup. In the case of Berkeley DB, the documentation describes a certain order in which database files can be copied that will guarantee a valid backup copy. A similar ordering exists for FSFS data. But you don't have to implement these algorithms yourself, because the Subversion development team has already done so. The <command>svnadmin hotcopy</command> command takes care of the minutia involved in making a hot backup of your repository. And its invocation is as trivial as Unix's <command>cp</command> or Windows' <command>copy</command> operations:"
8106 #: ../source/book.xml:11501
8108 msgid "\n$ svnadmin hotcopy /path/to/repos /path/to/repos-backup\n"
8112 #: ../source/book.xml:11504
8113 msgid "The resulting backup is a fully functional Subversion repository, able to be dropped in as a replacement for your live repository should something go horribly wrong."
8117 #: ../source/book.xml:11507
8118 msgid "When making copies of a Berkeley DB repository, you can even instruct <command>svnadmin hotcopy</command> to purge any unused Berkeley DB logfiles (see <xref linkend=\"svn.reposadmin.maint.diskspace.bdblogs\"/>) from the original repository upon completion of the copy. Simply provide the <option>--clean-logs</option> option on the command-line."
8122 #: ../source/book.xml:11513
8124 msgid "\n$ svnadmin hotcopy --clean-logs /path/to/bdb-repos /path/to/bdb-repos-backup\n"
8128 #: ../source/book.xml:11516
8129 msgid "Additional tooling around this command is available, too. The <filename>tools/backup/</filename> directory of the Subversion source distribution holds the <command>hot-backup.py</command> script. This script adds a bit of backup management atop <command>svnadmin hotcopy</command>, allowing you to keep only the most recent configured number of backups of each repository. It will automatically manage the names of the backed-up repository directories to avoid collisions with previous backups, and will <quote>rotate off</quote> older backups, deleting them so only the most recent ones remain. Even if you also have an incremental backup, you might want to run this program on a regular basis. For example, you might consider using <command>hot-backup.py</command> from a program scheduler (such as <command>cron</command> on Unix systems) which will cause it to run nightly (or at whatever granularity of Time you deem safe)."
8133 #: ../source/book.xml:11533
8134 msgid "Some administrators use a different backup mechanism built around generating and storing repository dump data. We described in <xref linkend=\"svn.reposadmin.maint.migrate\"/> how to use <command>svnadmin dump --incremental</command> to perform an incremental backup of a given revision or range of revisions. And of course, there is a full backup variation of this achieved by omitting the <option>--incremental</option> option to that command. There is some value in these methods, in that the format of your backed-up information is flexible—it's not tied to a particular platform, versioned filesystem type, or release of Subversion or Berkeley DB. But that flexibility comes at a cost, namely that restoring that data can take a long time—longer with each new revision committed to your repository. Also, as is the case with so many of the various backup methods, revision property changes made to already-backed-up revisions won't get picked up by a non-overlapping, incremental dump generation. For these reasons, we recommend against relying solely on dump-based backup approaches."
8138 #: ../source/book.xml:11552
8139 msgid "As you can see, each of the various backup types and methods has its advantages and disadvantages. The easiest is by far the full hot backup, which will always result in a perfect working replica of your repository. Should something bad happen to your live repository, you can restore from the backup with a simple recursive directory copy. Unfortunately, if you are maintaining multiple backups of your repository, these full copies will each eat up just as much disk space as your live repository. Incremental backups, by contrast, tend to be quicker to generate and smaller to store. But the restoration process can be a pain, often involving applying multiple incremental backups. And other methods have their own peculiarities. Administrators need to find the balance between the cost of making the backup and the cost of restoring it."
8143 #: ../source/book.xml:11567
8144 msgid "The <command>svnsync</command> program (see <xref linkend=\"svn.reposadmin.maint.replication\"/>) actually provides a rather handy middle-ground approach. If you are regularly synchronizing a read-only mirror with your main repository, then in a pinch, your read-only mirror is probably a good candidate for replacing that main repository if it falls over. The primary disadvantage of this method is that only the versioned repository data gets synchronized—repository configuration files, user-specified repository path locks, and other items which might live in the physical repository directory but not <emphasis>inside</emphasis> the repository's virtual versioned filesystem are not handled by svnsync."
8148 #: ../source/book.xml:11585
8149 msgid "<command>svnadmin setlog</command> can be called in a way that bypasses the hook interface altogether."
8153 #: ../source/book.xml:11579
8154 msgid "In any backup scenario, repository administrators need to be aware of how modifications to unversioned revision properties affect their backups. Since these changes do not themselves generate new revisions, they will not trigger post-commit hooks, and may not even trigger the pre-revprop-change and post-revprop-change hooks. <placeholder-1/> And since you can change revision properties without respect to chronological order—you can change any revision's properties at any time—an incremental backup of the latest few revisions might not catch a property modification to a revision that was included as part of a previous backup."
8158 #: ../source/book.xml:11593
8159 msgid "Generally speaking, only the truly paranoid would need to backup their entire repository, say, every time a commit occurred. However, assuming that a given repository has some other redundancy mechanism in place with relatively fine granularity (like per-commit emails or incremental dumps), a hot backup of the database might be something that a repository administrator would want to include as part of a system-wide nightly backup. It's your data—protect it as much as you'd like."
8163 #: ../source/book.xml:11616
8164 msgid "You know—the collective term for all of her <quote>fickle fingers</quote>."
8168 #: ../source/book.xml:11602
8169 msgid "Often, the best approach to repository backups is a diversified one which leverages combinations of the methods described here. The Subversion developers, for example, back up the Subversion source code repository nightly using <command>hot-backup.py</command> and an offsite <command>rsync</command> of those full backups; keep multiple archives of all the commit and property change notification emails; and have repository mirrors maintained by various volunteers using <command>svnsync</command>. Your solution might be similar, but should be catered to your needs and that delicate balance of convenience with paranoia. And whatever you do, validate your backups from time to time—what good is a spare tire that has a hole in it? While all of this might not save your hardware from the iron fist of Fate, <placeholder-1/> it should certainly help you recover from those trying times."
8173 #: ../source/book.xml:11629
8174 msgid "By now you should have a basic understanding of how to create, configure, and maintain Subversion repositories. We've introduced you to the various tools that will assist you with this task. Throughout the chapter, we've noted common administration pitfalls, and suggestions for avoiding them."
8178 #: ../source/book.xml:11635
8179 msgid "All that remains is for you to decide what exciting data to store in your repository, and finally, how to make it available over a network. The next chapter is all about networking."
8183 #: ../source/book.xml:11647
8184 msgid "Server Configuration"
8188 #: ../source/book.xml:11649
8189 msgid "A Subversion repository can be accessed simultaneously by clients running on the same machine on which the repository resides using the <literal>file://</literal> method. But the typical Subversion setup involves a single server machine being accessed from clients on computers all over the office—or, perhaps, all over the world."
8193 #: ../source/book.xml:11655
8194 msgid "This chapter describes how to get your Subversion repository exposed outside its host machine for use by remote clients. We will cover Subversion's currently available server mechanisms, discussing the configuration and use of each. After reading this section, you should be able to decide which networking setup is right for your needs, and understand how to enable such a setup on your host computer."
8198 #: ../source/book.xml:11667
8203 #: ../source/book.xml:11669
8204 msgid "Subversion was designed with an abstract network layer. This means that a repository can be programmatically accessed by any sort of server process, and the client <quote>repository access</quote> API allows programmers to write plugins that speak relevant network protocols. In theory, Subversion can use an infinite number of network implementations. In practice, there are only two servers at the time of this writing."
8208 #: ../source/book.xml:11676
8209 msgid "Apache is an extremely popular webserver; using the <command>mod_dav_svn</command> module, Apache can access a repository and make it available to clients via the WebDAV/DeltaV protocol, which is an extension of HTTP. Because Apache is an extremely extensible web server, it provides a number of features <quote>for free</quote>, such as encrypted SSL communication, logging, integration with a number of third-party authentication systems, and limited built-in web browsing of repositories."
8213 #: ../source/book.xml:11685
8214 msgid "In the other corner is <command>svnserve</command>: a small, lightweight server program that speaks a custom protocol with clients. Because its protocol is explicitly designed for Subversion and is stateful (unlike HTTP), it provides significantly faster network operations—but at the cost of some features as well. It only understands CRAM-MD5 authentication, has no logging, no web-browsing, and no option to encrypt network traffic. It is, however, extremely easy to set up and is often the best option for small teams just starting out with Subversion."
8218 #: ../source/book.xml:11695
8219 msgid "A third option is to use <command>svnserve</command> tunneled over an SSH connection. Even though this scenario still uses <command>svnserve</command>, it differs quite a bit in features from a traditional <command>svnserve</command> deployment. SSH is used to encrypt all communication. SSH is also used exclusively to authenticate, so real system accounts are required on the server host (unlike vanilla <command>svnserve</command>, which has its own private user accounts.) Finally, because this setup requires that each user spawn a private, temporary <command>svnserve</command> process, it's equivalent (from a permissions point of view) to allowing a group of local users to all access the repository via <literal>file://</literal> URLs. Path-based access control has no meaning, since each user is accessing the repository database files directly."
8223 #: ../source/book.xml:11710
8224 msgid "Here's a quick summary of the three typical server deployments."
8228 #: ../source/book.xml:11714
8229 msgid "Comparison of Subversion Server Options"
8233 #: ../source/book.xml:11720
8234 msgid "Apache + mod_dav_svn"
8238 #: ../source/book.xml:11722
8239 msgid "svnserve over SSH"
8243 #: ../source/book.xml:11727
8244 msgid "Authentication options"
8248 #: ../source/book.xml:11728
8249 msgid "HTTP(S) basic auth, X.509 certificates, LDAP, NTLM, or any other mechanism available to Apache httpd"
8253 #: ../source/book.xml:11730
8258 #: ../source/book.xml:11731
8263 #: ../source/book.xml:11734
8264 msgid "User account options"
8268 #: ../source/book.xml:11735 ../source/book.xml:11736
8269 msgid "private 'users' file"
8273 #: ../source/book.xml:11737
8274 msgid "system accounts"
8278 #: ../source/book.xml:11740
8279 msgid "Authorization options"
8283 #: ../source/book.xml:11741 ../source/book.xml:11743
8284 msgid "read/write access can be granted over whole repository, or specified per-path."
8288 #: ../source/book.xml:11745
8289 msgid "read/write access only grantable over whole repository"
8293 #: ../source/book.xml:11749
8298 #: ../source/book.xml:11750
8299 msgid "via optional SSL"
8303 #: ../source/book.xml:11751
8308 #: ../source/book.xml:11752
8309 msgid "SSH tunneled"
8313 #: ../source/book.xml:11755
8318 #: ../source/book.xml:11757
8323 #: ../source/book.xml:11756
8324 msgid "full Apache logs of each HTTP request, with optional <placeholder-1/> logging of general client operations"
8328 #: ../source/book.xml:11759 ../source/book.xml:11760
8333 #: ../source/book.xml:11763
8334 msgid "Interoperability"
8338 #: ../source/book.xml:11764
8339 msgid "partially usable by other WebDAV clients"
8343 #: ../source/book.xml:11765 ../source/book.xml:11766
8344 msgid "only talks to svn clients"
8348 #: ../source/book.xml:11769
8353 #: ../source/book.xml:11770
8354 msgid "limited built-in support, or via 3rd-party tools such as ViewVC"
8358 #: ../source/book.xml:11772 ../source/book.xml:11773
8359 msgid "only via 3rd-party tools such as ViewVC"
8363 #: ../source/book.xml:11776
8368 #: ../source/book.xml:11777
8369 msgid "somewhat slower"
8373 #: ../source/book.xml:11778 ../source/book.xml:11779
8374 msgid "somewhat faster"
8378 #: ../source/book.xml:11782 ../source/book.xml:12607
8379 msgid "Initial setup"
8383 #: ../source/book.xml:11783
8384 msgid "somewhat complex"
8388 #: ../source/book.xml:11784
8389 msgid "extremely simple"
8393 #: ../source/book.xml:11785
8394 msgid "moderately simple"
8398 #: ../source/book.xml:11793
8399 msgid "Choosing a Server Configuration"
8403 #: ../source/book.xml:11795
8404 msgid "So, which server should you use? Which is best?"
8408 #: ../source/book.xml:11796
8409 msgid "Obviously, there's no right answer to that question. Every team has different needs, and the different servers all represent different sets of tradeoffs. The Subversion project itself doesn't endorse one server or another, or consider either server more <quote>official</quote> than another."
8413 #: ../source/book.xml:11801
8414 msgid "Here are some reasons why you might choose one deployment over another, as well as reasons you might <emphasis>not</emphasis> choose one."
8418 #: ../source/book.xml:11806
8419 msgid "The <command>svnserve</command> Server"
8423 #: ../source/book.xml:11810 ../source/book.xml:11863 ../source/book.xml:11912
8424 msgid "Why you might want to use it:"
8428 #: ../source/book.xml:11814
8429 msgid "Quick and easy to set up."
8433 #: ../source/book.xml:11818 ../source/book.xml:11867
8434 msgid "Network protocol is stateful and noticeably faster than WebDAV."
8438 #: ../source/book.xml:11822 ../source/book.xml:11921
8439 msgid "No need to create system accounts on server."
8443 #: ../source/book.xml:11826
8444 msgid "Password is not passed over the network."
8448 #: ../source/book.xml:11833 ../source/book.xml:11882 ../source/book.xml:11948
8449 msgid "Why you might want to avoid it:"
8453 #: ../source/book.xml:11837
8454 msgid "Network protocol is not encrypted."
8458 #: ../source/book.xml:11841 ../source/book.xml:11886
8459 msgid "Only one choice of authentication method."
8463 #: ../source/book.xml:11845
8464 msgid "Password is stored in the clear on the server."
8468 #: ../source/book.xml:11849 ../source/book.xml:11890
8469 msgid "No logging of any kind, not even errors."
8473 #: ../source/book.xml:11859
8474 msgid "<command>svnserve</command> over SSH"
8478 #: ../source/book.xml:11871
8479 msgid "You can take advantage of existing ssh accounts and user infrastructure."
8483 #: ../source/book.xml:11875
8484 msgid "All network traffic is encrypted."
8488 #: ../source/book.xml:11894
8489 msgid "Requires users to be in same system group, or use a shared ssh key."
8493 #: ../source/book.xml:11898
8494 msgid "If used improperly, can lead to file permissions problems."
8498 #: ../source/book.xml:11908
8499 msgid "The Apache HTTP Server"
8503 #: ../source/book.xml:11916
8504 msgid "Allows Subversion to use any of the numerous authentication systems already integrated with Apache."
8508 #: ../source/book.xml:11925
8509 msgid "Full Apache logging."
8513 #: ../source/book.xml:11928
8514 msgid "Network traffic can be encrypted via SSL."
8518 #: ../source/book.xml:11932
8519 msgid "HTTP(S) can usually go through corporate firewalls."
8523 #: ../source/book.xml:11936
8524 msgid "Built-in repository browsing via web browser."
8528 #: ../source/book.xml:11940
8529 msgid "Repository can be mounted as a network drive for transparent version control. (See <xref linkend=\"svn.webdav.autoversioning\"/>.)"
8533 #: ../source/book.xml:11952
8534 msgid "Noticeably slower than svnserve, because HTTP is a stateless protocol and requires more turnarounds."
8538 #: ../source/book.xml:11957
8539 msgid "Initial setup can be complex."
8543 #: ../source/book.xml:11966
8544 msgid "Recommendations"
8548 #: ../source/book.xml:11968
8549 msgid "In general, the authors of this book recommend a vanilla <command>svnserve</command> installation for small teams just trying to get started with a Subversion server; it's the simplest to set up, and has the fewest maintenance issues. You can always switch to a more complex server deployment as your needs change."
8553 #: ../source/book.xml:11974
8554 msgid "Here are some general recommendations and tips, based on years of supporting users:"
8558 #: ../source/book.xml:11978
8559 msgid "If you're trying to set up the simplest possible server for your group, then a vanilla <command>svnserve</command> installation is the easiest, fastest route. Note, however, that your repository data will be transmitted in the clear over the network. If your deployment is entirely within your company's LAN or VPN, this isn't an issue. If the repository is exposed to the wide-open internet, then you might want to make sure the repository's contents aren't sensitive (e.g. it contains only open-source code.)"
8563 #: ../source/book.xml:11990
8564 msgid "If you need to integrate with existing identity systems (LDAP, Active Directory, NTLM, X.509, etc.), then an Apache-based server is your only real option. Similarly, if you absolutely need server-side logs of either server errors or client activities, then an Apache-based server is required."
8568 #: ../source/book.xml:11998
8569 msgid "If you've decided to use either Apache or stock <command>svnserve</command>, create a single <literal>svn</literal> user on your system and run the server process as that user. Be sure to make the repository directory wholly owned by the <literal>svn</literal> user as well. From a security point of view, this keeps the repository data nicely siloed and protected by operating system filesystem permissions, changeable by only the Subversion server process itself."
8573 #: ../source/book.xml:12010
8574 msgid "If you have an existing infrastructure heavily based on SSH accounts, and if your users already have system accounts on your server machine, then it makes sense to deploy an svnserve-over-ssh solution. Otherwise, we don't widely recommend this option to the public. It's generally considered safer to have your users access the repository via (imaginary) accounts managed by <command>svnserve</command> or Apache, rather than by full-blown system accounts. If your deep desire for encrypted communication still draws you to this option, we recommend using Apache with SSL instead."
8578 #: ../source/book.xml:12023
8579 msgid "Do <emphasis>not</emphasis> be seduced by the simple idea of having all of your users access a repository directly via <literal>file://</literal> URLs. Even if the repository is readily available to everyone via network share, this is a bad idea. It removes any layers of protection between the users and the repository: users can accidentally (or intentionally) corrupt the repository database, it becomes hard to take the repository offline for inspection or upgrade, and it can lead to a mess of file-permissions problems (see <xref linkend=\"svn.serverconfig.multimethod\"/>.) Note that this is also one of the reasons we warn against accessing repositories via <literal>svn+ssh://</literal> URLs—from a security standpoint, it's effectively the same as local users accessing via <literal>file://</literal>, and can entail all the same problems if the administrator isn't careful."
8583 #: ../source/book.xml:12049
8584 msgid "svnserve, a custom server"
8588 #: ../source/book.xml:12051
8589 msgid "The <command>svnserve</command> program is a lightweight server, capable of speaking to clients over TCP/IP using a custom, stateful protocol. Clients contact an <command>svnserve</command> server by using URLs that begin with the <literal>svn://</literal> or <literal>svn+ssh://</literal> scheme. This section will explain the different ways of running <command>svnserve</command>, how clients authenticate themselves to the server, and how to configure appropriate access control to your repositories."
8593 #: ../source/book.xml:12063
8594 msgid "Invoking the Server"
8598 #: ../source/book.xml:12065
8599 msgid "There are a few different ways to run the <command>svnserve</command> program:"
8603 #: ../source/book.xml:12069
8604 msgid "Run <command>svnserve</command> as a standalone daemon, listening for requests."
8608 #: ../source/book.xml:12074
8609 msgid "Have the Unix <command>inetd</command> daemon temporarily spawn <command>svnserve</command> whenever a request comes in on a certain port."
8613 #: ../source/book.xml:12079
8614 msgid "Have SSH invoke a temporary <command>svnserve</command> over an encrypted tunnel."
8618 #: ../source/book.xml:12084
8619 msgid "Run <command>svnserve</command> as a Windows service."
8623 #: ../source/book.xml:12091
8624 msgid "<command>svnserve</command> as Daemon"
8628 #: ../source/book.xml:12093
8629 msgid "The easiest option is to run <command>svnserve</command> as a standalone <quote>daemon</quote> process. Use the <option>-d</option> option for this:"
8633 #: ../source/book.xml:12096
8635 msgid "\n$ svnserve -d\n$ # svnserve is now running, listening on port 3690\n"
8639 #: ../source/book.xml:12100
8640 msgid "When running <command>svnserve</command> in daemon mode, you can use the <option>--listen-port=</option> and <option>--listen-host=</option> options to customize the exact port and hostname to <quote>bind</quote> to."
8644 #: ../source/book.xml:12104
8645 msgid "Once we successfully start <command>svnserve</command> as above, it makes every repository on your system available to the network. A client needs to specify an <emphasis>absolute</emphasis> path in the repository URL. For example, if a repository is located at <filename>/usr/local/repositories/project1</filename>, then a client would reach it via <uri>svn://host.example.com/usr/local/repositories/project1</uri>. To increase security, you can pass the <option>-r</option> option to <command>svnserve</command>, which restricts it to exporting only repositories below that path. For example:"
8649 #: ../source/book.xml:12115
8651 msgid "\n$ svnserve -d -r /usr/local/repositories\n…\n"
8655 #: ../source/book.xml:12119
8656 msgid "Using the <option>-r</option> option effectively modifies the location that the program treats as the root of the remote filesystem space. Clients then use URLs that have that path portion removed from them, leaving much shorter (and much less revealing) URLs:"
8660 #: ../source/book.xml:12124
8662 msgid "\n$ svn checkout svn://host.example.com/project1\n…\n"
8666 #: ../source/book.xml:12132
8667 msgid "<command>svnserve</command> via <command>inetd</command>"
8671 #: ../source/book.xml:12134
8672 msgid "If you want <command>inetd</command> to launch the process, then you need to pass the <option>-i</option> (<option>--inetd</option>) option. In the example, we've shown the output from running <literal>svnserve -i</literal> at the command line, but note that isn't how you actually start the daemon; see the paragraphs following the example for how to configure <command>inetd</command> to start <command>svnserve</command>."
8676 #: ../source/book.xml:12142
8678 msgid "\n$ svnserve -i\n( success ( 1 2 ( ANONYMOUS ) ( edit-pipeline ) ) )\n"
8682 #: ../source/book.xml:12146
8683 msgid "When invoked with the <option>--inetd</option> option, <command>svnserve</command> attempts to speak with a Subversion client via <emphasis>stdin</emphasis> and <emphasis>stdout</emphasis> using a custom protocol. This is the standard behavior for a program being run via <command>inetd</command>. The IANA has reserved port 3690 for the Subversion protocol, so on a Unix-like system you can add lines to <filename>/etc/services</filename> like these (if they don't already exist):"
8687 #: ../source/book.xml:12155
8689 msgid "\nsvn 3690/tcp # Subversion\nsvn 3690/udp # Subversion\n"
8693 #: ../source/book.xml:12159
8694 msgid "And if your system is using a classic Unix-like <command>inetd</command> daemon, you can add this line to <filename>/etc/inetd.conf</filename>:"
8698 #: ../source/book.xml:12162
8700 msgid "\nsvn stream tcp nowait svnowner /usr/bin/svnserve svnserve -i\n"
8704 #: ../source/book.xml:12165
8705 msgid "Make sure <quote>svnowner</quote> is a user which has appropriate permissions to access your repositories. Now, when a client connection comes into your server on port 3690, <command>inetd</command> will spawn an <command>svnserve</command> process to service it. Of course, you may also want to add <option>-r</option> to the configuration line as well, to restrict which repositories are exported."
8709 #: ../source/book.xml:12177
8710 msgid "<command>svnserve</command> over a Tunnel"
8714 #: ../source/book.xml:12179
8715 msgid "A third way to invoke <command>svnserve</command> is in <quote>tunnel mode</quote>, with the <option>-t</option> option. This mode assumes that a remote-service program such as <command>RSH</command> or <command>SSH</command> has successfully authenticated a user and is now invoking a private <command>svnserve</command> process <emphasis>as that user</emphasis>. (Note that you, the user, will rarely, if ever, have reason to invoke <command>svnserve</command> with the <option>-t</option> at the command line; instead, the <command>SSH</command> daemon does so for you.) The <command>svnserve</command> program behaves normally (communicating via <emphasis>stdin</emphasis> and <emphasis>stdout</emphasis>), and assumes that the traffic is being automatically redirected over some sort of tunnel back to the client. When <command>svnserve</command> is invoked by a tunnel agent like this, be sure that the authenticated user has full read and write access to the repository database files. It's essentially the same as a local user accessing the repository via <literal>file://</literal> URLs."
8719 #: ../source/book.xml:12199
8720 msgid "This option is described in much more detail in <xref linkend=\"svn.serverconfig.svnserve.sshauth\"/>."
8724 #: ../source/book.xml:12205
8725 msgid "<command>svnserve</command> as Windows Service"
8729 #: ../source/book.xml:12207
8730 msgid "If your Windows system is a descendant of Windows NT (2000, 2003, XP, Vista), then you can run <command>svnserve</command> as a standard Windows service. This is typically a much nicer experience than running it as a standalone daemon with the <option>--daemon (-d)</option> option. Using daemon-mode requires launching a console, typing a command, and then leaving the console window running indefinitely. A Windows service, however, runs in the background, can start at boot time automatically, and can be started and stopped using the same consistent administration interface as other Windows services."
8734 #: ../source/book.xml:12219
8735 msgid "You'll need to define the new service using the command-line tool <command>SC.EXE</command>. Much like the <command>inetd</command> configuration line, you must specify an exact invocation of <command>svnserve</command> for Windows to run at start-up time:"
8739 #: ../source/book.xml:12224
8741 msgid "\nC:\\> sc create svn\n binpath= \"C:\\svn\\bin\\svnserve.exe --service -r C:\\repos\"\n displayname= \"Subversion Server\"\n depend= Tcpip\n start= auto\n"
8745 #: ../source/book.xml:12231
8746 msgid "This defines a new Windows service named <quote>svn</quote>, and which executes a particular <command>svnserve.exe</command> command when started (in this case, rooted at <filename>C:\\repos</filename>.) There are a number of caveats in the prior example, however."
8750 #: ../source/book.xml:12237
8751 msgid "First, notice that the <command>svnserve.exe</command> program must always be invoked with the <option>--service</option> option. Any other options to <command>svnserve</command> must then be specified on the same line, but you cannot add conflicting options such as <option>--daemon (-d)</option>, <option>--tunnel</option>, or <option>--inetd (-i)</option>. Options such as <option>-r</option> or <option>--listen-port</option> are fine, though. Second, be careful about spaces when invoking the <command>SC.EXE</command> command: the <literal>key= value</literal> patterns must have no spaces between <literal>key=</literal> and exactly one space before the <literal>value</literal>. Lastly, be careful about spaces in your command-line to be invoked. If a directory name contains spaces (or other characters that need escaping), place the entire inner value of <literal>binpath</literal> in double-quotes, by escaping them:"
8755 #: ../source/book.xml:12256
8757 msgid "\nC:\\> sc create svn\n binpath= \"\\\"C:\\program files\\svn\\bin\\svnserve.exe\\\" --service -r C:\\repos\"\n displayname= \"Subversion Server\"\n depend= Tcpip\n start= auto\n"
8761 #: ../source/book.xml:12263
8762 msgid "Also note that the word <literal>binpath</literal> is misleading—its value is a <emphasis>command line</emphasis>, not the path to an executable. That's why you need to surround it with quote marks if it contains embedded spaces."
8766 #: ../source/book.xml:12268
8767 msgid "Once the service is defined, it can stopped, started, or queried using standard GUI tools (the Services administrative control panel), or at the command line as well:"
8771 #: ../source/book.xml:12272
8773 msgid "\nC:\\> net stop svn\nC:\\> net start svn\n"
8777 #: ../source/book.xml:12276
8778 msgid "The service can also be uninstalled (i.e. undefined) by deleting its definition: <literal>sc delete svn</literal>. Just be sure to stop the service first! The <command>SC.EXE</command> program has many other subcommands and options; run <literal>sc /?</literal> to learn more about it."
8782 #: ../source/book.xml:12287
8783 msgid "Built-in authentication and authorization"
8787 #: ../source/book.xml:12289
8788 msgid "When a client connects to an <command>svnserve</command> process, the following things happen:"
8792 #: ../source/book.xml:12293
8793 msgid "The client selects a specific repository."
8797 #: ../source/book.xml:12297
8798 msgid "The server processes the repository's <filename>conf/svnserve.conf</filename> file, and begins to enforce any authentication and authorization policies defined therein."
8802 #: ../source/book.xml:12303
8803 msgid "Depending on the situation and authorization policies,"
8807 #: ../source/book.xml:12307
8808 msgid "the client may be allowed to make requests anonymously, without ever receiving an authentication challenge, OR"
8812 #: ../source/book.xml:12312
8813 msgid "the client may be challenged for authentication at any time, OR"
8817 #: ../source/book.xml:12316
8818 msgid "if operating in <quote>tunnel mode</quote>, the client will declare itself to be already externally authenticated."
8822 #: ../source/book.xml:12324
8823 msgid "See RFC 2195."
8827 #: ../source/book.xml:12323
8828 msgid "At the time of writing, the server only knows how to send a CRAM-MD5 <placeholder-1/> authentication challenge. In essence, the server sends a small amount of data to the client. The client uses the MD5 hash algorithm to create a fingerprint of the data and password combined, then sends the fingerprint as a response. The server performs the same computation with the stored password to verify that the result is identical. <emphasis>At no point does the actual password travel over the network.</emphasis>"
8832 #: ../source/book.xml:12333
8833 msgid "It's also possible, of course, for the client to be externally authenticated via a tunnel agent, such as <command>SSH</command>. In that case, the server simply examines the user it's running as, and uses it as the authenticated username. For more on this, see <xref linkend=\"svn.serverconfig.svnserve.sshauth\"/>."
8837 #: ../source/book.xml:12338
8838 msgid "As you've already guessed, a repository's <filename>svnserve.conf</filename> file is the central mechanism for controlling authentication and authorization policies. The file has the same format as other configuration files (see <xref linkend=\"svn.advanced.confarea\"/>): section names are marked by square brackets (<literal>[</literal> and <literal>]</literal>), comments begin with hashes (<literal>#</literal>), and each section contains specific variables that can be set (<literal>variable = value</literal>). Let's walk through these files and learn how to use them."
8842 #: ../source/book.xml:12352
8843 msgid "Create a 'users' file and realm"
8847 #: ../source/book.xml:12354
8848 msgid "For now, the <literal>[general]</literal> section of the <filename>svnserve.conf</filename> has all the variables you need. Begin by changing the values of those variables: choose a name for a file which will contain your usernames and passwords, and choose an authentication realm:"
8852 #: ../source/book.xml:12359
8854 msgid "\n[general]\npassword-db = userfile\nrealm = example realm\n"
8858 #: ../source/book.xml:12364
8859 msgid "The <literal>realm</literal> is a name that you define. It tells clients which sort of <quote>authentication namespace</quote> they're connecting to; the Subversion client displays it in the authentication prompt, and uses it as a key (along with the server's hostname and port) for caching credentials on disk (see <xref linkend=\"svn.serverconfig.netmodel.credcache\"/>). The <literal>password-db</literal> variable points to a separate file that contains a list of usernames and passwords, using the same familiar format. For example:"
8863 #: ../source/book.xml:12373
8865 msgid "\n[users]\nharry = foopassword\nsally = barpassword\n"
8869 #: ../source/book.xml:12378
8870 msgid "The value of <literal>password-db</literal> can be an absolute or relative path to the users file. For many admins, it's easy to keep the file right in the <filename>conf/</filename> area of the repository, alongside <filename>svnserve.conf</filename>. On the other hand, it's possible you may want to have two or more repositories share the same users file; in that case, the file should probably live in a more public place. The repositories sharing the users file should also be configured to have the same realm, since the list of users essentially defines an authentication realm. Wherever the file lives, be sure to set the file's read and write permissions appropriately. If you know which user(s) <command>svnserve</command> will run as, restrict read access to the user file as necessary."
8874 #: ../source/book.xml:12396
8875 msgid "Set access controls"
8879 #: ../source/book.xml:12398
8880 msgid "There are two more variables to set in the <filename>svnserve.conf</filename> file: they determine what unauthenticated (anonymous) and authenticated users are allowed to do. The variables <literal>anon-access</literal> and <literal>auth-access</literal> can be set to the values <literal>none</literal>, <literal>read</literal>, or <literal>write</literal>. Setting the value to <literal>none</literal> prohibits both reading and writing; <literal>read</literal> allows read-only access to the repository, and <literal>write</literal> allows complete read/write access to the repository. For example:"
8884 #: ../source/book.xml:12409
8886 msgid "\n[general]\npassword-db = userfile\nrealm = example realm\n\n# anonymous users can only read the repository\nanon-access = read\n\n# authenticated users can both read and write\nauth-access = write\n"
8890 #: ../source/book.xml:12420
8891 msgid "The example settings are, in fact, the default values of the variables, should you forget to define them. If you want to be even more conservative, you can block anonymous access completely:"
8895 #: ../source/book.xml:12424
8897 msgid "\n[general]\npassword-db = userfile\nrealm = example realm\n\n# anonymous users aren't allowed\nanon-access = none\n\n# authenticated users can both read and write\nauth-access = write\n"
8901 #: ../source/book.xml:12435
8902 msgid "The server process not only understands these <quote>blanket</quote> access controls to the repository, but also finer-grained access restrictions placed on specific files and directories within the repository. To make use of this feature, you need to define a file containing more detailed rules, and then set the <literal>authz-db</literal> variable to point to it:"
8906 #: ../source/book.xml:12442
8908 msgid "\n[general]\npassword-db = userfile\nrealm = example realm\n\n# Specific access rules for specific locations\nauthz-db = authzfile\n"
8912 #: ../source/book.xml:12450
8913 msgid "The syntax of the <filename>authzfile</filename> file is discussed in detail in <xref linkend=\"svn.serverconfig.pathbasedauthz\"/>. Note that the <literal>authz-db</literal> variable isn't mutually exclusive with the <literal>anon-access</literal> and <literal>auth-access</literal> variables; if all the variables are defined at once, then <emphasis>all</emphasis> of the rules must be satisfied before access is allowed."
8917 #: ../source/book.xml:12463
8918 msgid "Tunneling over SSH"
8922 #: ../source/book.xml:12465
8923 msgid "<command>svnserve</command>'s built-in authentication can be very handy, because it avoids the need to create real system accounts. On the other hand, some administrators already have well-established SSH authentication frameworks in place. In these situations, all of the project's users already have system accounts and the ability to <quote>SSH into</quote> the server machine."
8927 #: ../source/book.xml:12472
8928 msgid "It's easy to use SSH in conjunction with <command>svnserve</command>. The client simply uses the <literal>svn+ssh://</literal> URL scheme to connect:"
8932 #: ../source/book.xml:12475
8934 msgid "\n$ whoami\nharry\n\n$ svn list svn+ssh://host.example.com/repos/project\nharry@host.example.com's password: *****\n\nfoo\nbar\nbaz\n…\n"
8938 #: ../source/book.xml:12487
8939 msgid "In this example, the Subversion client is invoking a local <command>ssh</command> process, connecting to <literal>host.example.com</literal>, authenticating as the user <literal>harry</literal>, then spawning a private <command>svnserve</command> process on the remote machine running as the user <literal>harry</literal>. The <command>svnserve</command> command is being invoked in tunnel mode (<option>-t</option>) and its network protocol is being <quote>tunneled</quote> over the encrypted connection by <command>ssh</command>, the tunnel-agent. <command>svnserve</command> is aware that it's running as the user <literal>harry</literal>, and if the client performs a commit, the authenticated username will be used as the author of the new revision."
8943 #: ../source/book.xml:12501
8944 msgid "The important thing to understand here is that the Subversion client is <emphasis>not</emphasis> connecting to a running <command>svnserve</command> daemon. This method of access doesn't require a daemon, nor does it notice one if present. It relies wholly on the ability of <command>ssh</command> to spawn a temporary <command>svnserve</command> process, which then terminates when the network connection is closed."
8948 #: ../source/book.xml:12509
8949 msgid "When using <literal>svn+ssh://</literal> URLs to access a repository, remember that it's the <command>ssh</command> program prompting for authentication, and <emphasis>not</emphasis> the <command>svn</command> client program. That means there's no automatic password caching going on (see <xref linkend=\"svn.serverconfig.netmodel.credcache\"/>). The Subversion client often makes multiple connections to the repository, though users don't normally notice this due to the password caching feature. When using <literal>svn+ssh://</literal> URLs, however, users may be annoyed by <command>ssh</command> repeatedly asking for a password for every outbound connection. The solution is to use a separate SSH password-caching tool like <command>ssh-agent</command> on a Unix-like system, or <command>pageant</command> on Windows."
8953 #: ../source/book.xml:12536
8954 msgid "Note that using any sort of <command>svnserve</command>-enforced access control at all is a bit pointless; the user already has direct access to the repository database."
8958 #: ../source/book.xml:12524
8959 msgid "When running over a tunnel, authorization is primarily controlled by operating system permissions to the repository's database files; it's very much the same as if Harry were accessing the repository directly via a <literal>file://</literal> URL. If multiple system users are going to be accessing the repository directly, you may want to place them into a common group, and you'll need to be careful about umasks. (Be sure to read <xref linkend=\"svn.serverconfig.multimethod\"/>.) But even in the case of tunneling, the <filename>svnserve.conf</filename> file can still be used to block access, by simply setting <literal>auth-access = read</literal> or <literal>auth-access = none</literal>. <placeholder-1/>"
8963 #: ../source/book.xml:12545
8964 msgid "We don't actually recommend this, since RSH is notably less secure than SSH."
8968 #: ../source/book.xml:12541
8969 msgid "You'd think that the story of SSH tunneling would end here, but it doesn't. Subversion allows you to create custom tunnel behaviors in your run-time <filename>config</filename> file (see <xref linkend=\"svn.advanced.confarea\"/>). For example, suppose you want to use RSH instead of SSH<placeholder-1/>. In the <literal>[tunnels]</literal> section of your <filename>config</filename> file, simply define it like this:"
8973 #: ../source/book.xml:12551
8975 msgid "\n[tunnels]\nrsh = rsh\n"
8979 #: ../source/book.xml:12555
8980 msgid "And now, you can use this new tunnel definition by using a URL scheme that matches the name of your new variable: <literal>svn+rsh://host/path</literal>. When using the new URL scheme, the Subversion client will actually be running the command <command>rsh host svnserve -t</command> behind the scenes. If you include a username in the URL (for example, <literal>svn+rsh://username@host/path</literal>) the client will also include that in its command (<command>rsh username@host svnserve -t</command>). But you can define new tunneling schemes to be much more clever than that:"
8984 #: ../source/book.xml:12565
8986 msgid "\n[tunnels]\njoessh = $JOESSH /opt/alternate/ssh -p 29934\n"
8990 #: ../source/book.xml:12569
8991 msgid "This example demonstrates a couple of things. First, it shows how to make the Subversion client launch a very specific tunneling binary (the one located at <filename>/opt/alternate/ssh</filename>) with specific options. In this case, accessing a <literal>svn+joessh://</literal> URL would invoke the particular SSH binary with <option>-p 29934</option> as arguments—useful if you want the tunnel program to connect to a non-standard port."
8995 #: ../source/book.xml:12578
8996 msgid "Second, it shows how to define a custom environment variable that can override the name of the tunneling program. Setting the <literal>SVN_SSH</literal> environment variable is a convenient way to override the default SSH tunnel agent. But if you need to have several different overrides for different servers, each perhaps contacting a different port or passing a different set of options to SSH, you can use the mechanism demonstrated in this example. Now if we were to set the <literal>JOESSH</literal> environment variable, its value would override the entire value of the tunnel variable—<command>$JOESSH</command> would be executed instead of <command>/opt/alternate/ssh -p 29934</command>."
9000 #: ../source/book.xml:12595
9001 msgid "SSH configuration tricks"
9005 #: ../source/book.xml:12597
9006 msgid "It's not only possible to control the way in which the client invokes <command>ssh</command>, but also to control the behavior of <command>sshd</command> on your server machine. In this section, we'll show how to control the exact <command>svnserve</command> command executed by <command>sshd</command>, as well as how to have multiple users share a single system account."
9010 #: ../source/book.xml:12609
9011 msgid "To begin, locate the home directory of the account you'll be using to launch <command>svnserve</command>. Make sure the account has an SSH public/private keypair installed, and that the user can log in via public-key authentication. Password authentication will not work, since all of the following SSH tricks revolve around using the SSH <filename>authorized_keys</filename> file."
9015 #: ../source/book.xml:12616
9016 msgid "If it doesn't already exist, create the <filename>authorized_keys</filename> file (on Unix, typically <filename>~/.ssh/authorized_keys</filename>). Each line in this file describes a public key that is allowed to connect. The lines are typically of the form:"
9020 #: ../source/book.xml:12622
9022 msgid "\n ssh-dsa AAAABtce9euch… user@example.com\n"
9026 #: ../source/book.xml:12625
9027 msgid "The first field describes the type of key, the second field is the base64-encoded key itself, and the third field is a comment. However, it's a lesser known fact that the entire line can be preceded by a <literal>command</literal> field:"
9031 #: ../source/book.xml:12630
9033 msgid "\n command=\"program\" ssh-dsa AAAABtce9euch… user@example.com\n"
9037 #: ../source/book.xml:12633
9038 msgid "When the <literal>command</literal> field is set, the SSH daemon will run the named program instead of the typical <command>svnserve -t</command> invocation that the Subversion client asks for. This opens the door to a number of server-side tricks. In the following examples, we abbreviate the lines of the file as:"
9042 #: ../source/book.xml:12639
9044 msgid "\n command=\"program\" TYPE KEY COMMENT\n"
9048 #: ../source/book.xml:12646
9049 msgid "Controlling the invoked command"
9053 #: ../source/book.xml:12648
9054 msgid "Because we can specify the executed server-side command, it's easy to name a specific <command>svnserve</command> binary to run and to pass it extra arguments:"
9058 #: ../source/book.xml:12651
9060 msgid "\n command=\"/path/to/svnserve -t -r /virtual/root\" TYPE KEY COMMENT\n"
9064 #: ../source/book.xml:12654
9065 msgid "In this example, <filename>/path/to/svnserve</filename> might be a custom wrapper script around <command>svnserve</command> which sets the umask (see <xref linkend=\"svn.serverconfig.multimethod\"/>). It also shows how to anchor <command>svnserve</command> in a virtual root directory, just as one often does when running <command>svnserve</command> as a daemon process. This might be done either to restrict access to parts of the system, or simply to relieve the user of having to type an absolute path in the <literal>svn+ssh://</literal> URL."
9069 #: ../source/book.xml:12665
9070 msgid "It's also possible to have multiple users share a single account. Instead of creating a separate system account for each user, generate a public/private keypair for each person. Then place each public key into the <filename>authorized_users</filename> file, one per line, and use the <option>--tunnel-user</option> option:"
9074 #: ../source/book.xml:12672
9076 msgid "\n command=\"svnserve -t --tunnel-user=harry\" TYPE1 KEY1 harry@example.com\n command=\"svnserve -t --tunnel-user=sally\" TYPE2 KEY2 sally@example.com\n"
9080 #: ../source/book.xml:12676
9081 msgid "This example allows both Harry and Sally to connect to the same account via public-key authentication. Each of them has a custom command that will be executed; the <option>--tunnel-user</option> option tells <command>svnserve -t</command> to assume that the named argument is the authenticated user. Without <option>--tunnel-user</option>, it would appear as though all commits were coming from the one shared system account."
9085 #: ../source/book.xml:12685
9086 msgid "A final word of caution: giving a user access to the server via public-key in a shared account might still allow other forms of SSH access, even if you've set the <literal>command</literal> value in <filename>authorized_keys</filename>. For example, the user may still get shell access through SSH, or be able to perform X11 or general port-forwarding through your server. To give the user as little permission as possible, you may want to specify a number of restrictive options immediately after the <literal>command</literal>:"
9090 #: ../source/book.xml:12695
9092 msgid "\n command=\"svnserve -t --tunnel-user=harry\",no-port-forwarding,\\\n no-agent-forwarding,no-X11-forwarding,no-pty \\\n TYPE1 KEY1 harry@example.com\n"
9096 #: ../source/book.xml:12708
9097 msgid "httpd, the Apache HTTP server"
9101 #: ../source/book.xml:12723
9102 msgid "They really hate doing that."
9106 #: ../source/book.xml:12710
9107 msgid "The Apache HTTP Server is a <quote>heavy duty</quote> network server that Subversion can leverage. Via a custom module, <command>httpd</command> makes Subversion repositories available to clients via the WebDAV/DeltaV protocol, which is an extension to HTTP 1.1 (see <uri href=\"http://www.webdav.org/\">http://www.webdav.org/</uri> for more information). This protocol takes the ubiquitous HTTP protocol that is the core of the World Wide Web, and adds writing—specifically, versioned writing—capabilities. The result is a standardized, robust system that is conveniently packaged as part of the Apache 2.0 software, is supported by numerous operating systems and third-party products, and doesn't require network administrators to open up yet another custom port. <placeholder-1/> While an Apache-Subversion server has more features than <command>svnserve</command>, it's also a bit more difficult to set up. With flexibility often comes more complexity."
9111 #: ../source/book.xml:12727
9112 msgid "Much of the following discussion includes references to Apache configuration directives. While some examples are given of the use of these directives, describing them in full is outside the scope of this chapter. The Apache team maintains excellent documentation, publicly available on their website at <uri href=\"http://httpd.apache.org\">http://httpd.apache.org</uri>. For example, a general reference for the configuration directives is located at <uri href=\" http://httpd.apache.org/docs-2.0/mod/directives.html\"> http://httpd.apache.org/docs-2.0/mod/directives.html</uri>."
9116 #: ../source/book.xml:12734
9117 msgid "Also, as you make changes to your Apache setup, it is likely that somewhere along the way a mistake will be made. If you are not already familiar with Apache's logging subsystem, you should become aware of it. In your <filename>httpd.conf</filename> file are directives that specify the on-disk locations of the access and error logs generated by Apache (the <literal>CustomLog</literal> and <literal>ErrorLog</literal> directives, respectively). Subversion's mod_dav_svn uses Apache's error logging interface as well. You can always browse the contents of those files for information that might reveal the source of a problem that is not clearly noticeable otherwise."
9121 #: ../source/book.xml:12748
9122 msgid "Why Apache 2?"
9126 #: ../source/book.xml:12750
9127 msgid "If you're a system administrator, it's very likely that you're already running the Apache web server and have some prior experience with it. At the time of writing, Apache 1.3 is by far the most popular version of Apache. The world has been somewhat slow to upgrade to the Apache 2.X series for various reasons: some people fear change, especially changing something as critical as a web server. Other people depend on plug-in modules that only work against the Apache 1.3 API, and are waiting for a 2.X port. Whatever the reason, many people begin to worry when they first discover that Subversion's Apache module is written specifically for the Apache 2 API."
9131 #: ../source/book.xml:12761
9132 msgid "The proper response to this problem is: don't worry about it. It's easy to run Apache 1.3 and Apache 2 side-by-side; simply install them to separate places, and use Apache 2 as a dedicated Subversion server that runs on a port other than 80. Clients can access the repository by placing the port number into the URL:"
9136 #: ../source/book.xml:12767
9138 msgid "\n$ svn checkout http://host.example.com:7382/repos/project\n…\n"
9142 #: ../source/book.xml:12775
9143 msgid "Prerequisites"
9147 #: ../source/book.xml:12777
9148 msgid "To network your repository over HTTP, you basically need four components, available in two packages. You'll need Apache <command>httpd</command> 2.0, the <command>mod_dav</command> DAV module that comes with it, Subversion, and the <command>mod_dav_svn</command> filesystem provider module distributed with Subversion. Once you have all of those components, the process of networking your repository is as simple as:"
9152 #: ../source/book.xml:12787
9153 msgid "getting httpd 2.0 up and running with the mod_dav module,"
9157 #: ../source/book.xml:12791
9158 msgid "installing the mod_dav_svn plugin to mod_dav, which uses Subversion's libraries to access the repository, and"
9162 #: ../source/book.xml:12796
9163 msgid "configuring your <filename>httpd.conf</filename> file to export (or expose) the repository."
9167 #: ../source/book.xml:12800
9168 msgid "You can accomplish the first two items either by compiling <command>httpd</command> and Subversion from source code, or by installing pre-built binary packages of them on your system. For the most up-to-date information on how to compile Subversion for use with the Apache HTTP Server, as well as how to compile and configure Apache itself for this purpose, see the <filename>INSTALL</filename> file in the top level of the Subversion source code tree."
9172 #: ../source/book.xml:12812
9173 msgid "Basic Apache Configuration"
9177 #: ../source/book.xml:12814
9178 msgid "Once you have all the necessary components installed on your system, all that remains is the configuration of Apache via its <filename>httpd.conf</filename> file. Instruct Apache to load the mod_dav_svn module using the <literal>LoadModule</literal> directive. This directive must precede any other Subversion-related configuration items. If your Apache was installed using the default layout, your <command>mod_dav_svn</command> module should have been installed in the <filename>modules</filename> subdirectory of the Apache install location (often <filename>/usr/local/apache2</filename>). The <literal>LoadModule</literal> directive has a simple syntax, mapping a named module to the location of a shared library on disk:"
9182 #: ../source/book.xml:12828
9184 msgid "\nLoadModule dav_svn_module modules/mod_dav_svn.so\n"
9188 #: ../source/book.xml:12831
9189 msgid "Note that if <command>mod_dav</command> was compiled as a shared object (instead of statically linked directly to the <command>httpd</command> binary), you'll need a similar <literal>LoadModule</literal> statement for it, too. Be sure that it comes before the <command>mod_dav_svn</command> line:"
9193 #: ../source/book.xml:12836
9195 msgid "\nLoadModule dav_module modules/mod_dav.so\nLoadModule dav_svn_module modules/mod_dav_svn.so\n"
9199 #: ../source/book.xml:12840
9200 msgid "At a later location in your configuration file, you now need to tell Apache where you keep your Subversion repository (or repositories). The <literal>Location</literal> directive has an XML-like notation, starting with an opening tag, and ending with a closing tag, with various other configuration directives in the middle. The purpose of the <literal>Location</literal> directive is to instruct Apache to do something special when handling requests that are directed at a given URL or one of its children. In the case of Subversion, you want Apache to simply hand off support for URLs that point at versioned resources to the DAV layer. You can instruct Apache to delegate the handling of all URLs whose path portions (the part of the URL that follows the server's name and the optional port number) begin with <filename>/repos/</filename> to a DAV provider whose repository is located at <filename>/absolute/path/to/repository</filename> using the following <filename>httpd.conf</filename> syntax:"
9204 #: ../source/book.xml:12858
9206 msgid "\n<Location /repos>\n DAV svn\n SVNPath /absolute/path/to/repository\n</Location>\n"
9210 #: ../source/book.xml:12864
9211 msgid "If you plan to support multiple Subversion repositories that will reside in the same parent directory on your local disk, you can use an alternative directive, the <literal>SVNParentPath</literal> directive, to indicate that common parent directory. For example, if you know you will be creating multiple Subversion repositories in a directory <filename>/usr/local/svn</filename> that would be accessed via URLs like <uri>http://my.server.com/svn/repos1</uri>, <uri>http://my.server.com/svn/repos2</uri>, and so on, you could use the <filename>httpd.conf</filename> configuration syntax in the following example:"
9215 #: ../source/book.xml:12875
9217 msgid "\n<Location /svn>\n DAV svn\n\n # any \"/svn/foo\" URL will map to a repository /usr/local/svn/foo\n SVNParentPath /usr/local/svn\n</Location>\n"
9221 #: ../source/book.xml:12883
9222 msgid "Using the previous syntax, Apache will delegate the handling of all URLs whose path portions begin with <filename>/svn/</filename> to the Subversion DAV provider, which will then assume that any items in the directory specified by the <literal>SVNParentPath</literal> directive are actually Subversion repositories. This is a particularly convenient syntax in that, unlike the use of the <literal>SVNPath</literal> directive, you don't have to restart Apache in order to create and network new repositories."
9226 #: ../source/book.xml:12893
9227 msgid "Be sure that when you define your new <literal>Location</literal>, it doesn't overlap with other exported Locations. For example, if your main <literal>DocumentRoot</literal> is exported to <filename>/www</filename>, do not export a Subversion repository in <literal><Location /www/repos></literal>. If a request comes in for the URI <filename>/www/repos/foo.c</filename>, Apache won't know whether to look for a file <filename>repos/foo.c</filename> in the <literal>DocumentRoot</literal>, or whether to delegate <command>mod_dav_svn</command> to return <filename>foo.c</filename> from the Subversion repository. The result is often an error from the server of the form <literal>301 Moved Permanently</literal>."
9231 #: ../source/book.xml:12909
9232 msgid "Server Names and the COPY Request"
9236 #: ../source/book.xml:12911
9237 msgid "Subversion makes use of the <literal>COPY</literal> request type to perform server-side copies of files and directories. As part of the sanity checking done by the Apache modules, the source of the copy is expected to be located on the same machine as the destination of the copy. To satisfy this requirement, you might need to tell mod_dav the name you use as the hostname of your server. Generally, you can use the <literal>ServerName</literal> directive in <filename>httpd.conf</filename> to accomplish this."
9241 #: ../source/book.xml:12920
9243 msgid "\nServerName svn.example.com\n"
9247 #: ../source/book.xml:12923
9248 msgid "If you are using Apache's virtual hosting support via the <literal>NameVirtualHost</literal> directive, you may need to use the <literal>ServerAlias</literal> directive to specify additional names that your server is known by. Again, refer to the Apache documentation for full details."
9252 #: ../source/book.xml:12930
9253 msgid "At this stage, you should strongly consider the question of permissions. If you've been running Apache for some time now as your regular web server, you probably already have a collection of content—web pages, scripts and such. These items have already been configured with a set of permissions that allows them to work with Apache, or more appropriately, that allows Apache to work with those files. Apache, when used as a Subversion server, will also need the correct permissions to read and write to your Subversion repository."
9257 #: ../source/book.xml:12940
9258 msgid "You will need to determine a permission system setup that satisfies Subversion's requirements without messing up any previously existing web page or script installations. This might mean changing the permissions on your Subversion repository to match those in use by other things that Apache serves for you, or it could mean using the <literal>User</literal> and <literal>Group</literal> directives in <filename>httpd.conf</filename> to specify that Apache should run as the user and group that owns your Subversion repository. There is no single correct way to set up your permissions, and each administrator will have different reasons for doing things a certain way. Just be aware that permission-related problems are perhaps the most common oversight when configuring a Subversion repository for use with Apache."
9262 #: ../source/book.xml:12959
9263 msgid "Authentication Options"
9267 #: ../source/book.xml:12961
9268 msgid "At this point, if you configured <filename>httpd.conf</filename> to contain something like"
9272 #: ../source/book.xml:12963
9274 msgid "\n<Location /svn>\n DAV svn\n SVNParentPath /usr/local/svn\n</Location>\n"
9278 #: ../source/book.xml:12969
9279 msgid "…then your repository is <quote>anonymously</quote> accessible to the world. Until you configure some authentication and authorization policies, the Subversion repositories you make available via the <literal>Location</literal> directive will be generally accessible to everyone. In other words,"
9283 #: ../source/book.xml:12977
9284 msgid "anyone can use their Subversion client to check out a working copy of a repository URL (or any of its subdirectories),"
9288 #: ../source/book.xml:12982
9289 msgid "anyone can interactively browse the repository's latest revision simply by pointing their web browser to the repository URL, and"
9293 #: ../source/book.xml:12987
9294 msgid "anyone can commit to the repository."
9298 #: ../source/book.xml:12990
9299 msgid "Of course, you might have already set up a <filename>pre-commit</filename> hook script to prevent commits (see <xref linkend=\"svn.reposadmin.create.hooks\"/>). But as you read on, you'll see that it's also possible use Apache's built-in methods to restrict access in specific ways."
9303 #: ../source/book.xml:12999
9304 msgid "Basic HTTP Authentication"
9308 #: ../source/book.xml:13001
9309 msgid "The easiest way to authenticate a client is via the HTTP Basic authentication mechanism, which simply uses a username and password to verify that a user is who she says she is. Apache provides an <command>htpasswd</command> utility for managing the list of acceptable usernames and passwords. Let's grant commit access to Sally and Harry. First, we need to add them to the password file."
9313 #: ../source/book.xml:13009
9315 msgid "\n$ ### First time: use -c to create the file\n$ ### Use -m to use MD5 encryption of the password, which is more secure\n$ htpasswd -cm /etc/svn-auth-file harry\nNew password: *****\nRe-type new password: *****\nAdding password for user harry\n$ htpasswd -m /etc/svn-auth-file sally\nNew password: *******\nRe-type new password: *******\nAdding password for user sally\n$\n"
9319 #: ../source/book.xml:13022
9320 msgid "Next, you need to add some more <filename>httpd.conf</filename> directives inside your <literal>Location</literal> block to tell Apache what to do with your new password file. The <literal>AuthType</literal> directive specifies the type of authentication system to use. In this case, we want to specify the <literal>Basic</literal> authentication system. <literal>AuthName</literal> is an arbitrary name that you give for the authentication domain. Most browsers will display this name in the pop-up dialog box when the browser is querying the user for his name and password. Finally, use the <literal>AuthUserFile</literal> directive to specify the location of the password file you created using <command>htpasswd</command>."
9324 #: ../source/book.xml:13036
9325 msgid "After adding these three directives, your <literal><Location></literal> block should look something like this:"
9329 #: ../source/book.xml:13039
9331 msgid "\n<Location /svn>\n DAV svn\n SVNParentPath /usr/local/svn\n AuthType Basic\n AuthName \"Subversion repository\"\n AuthUserFile /etc/svn-auth-file\n</Location>\n"
9335 #: ../source/book.xml:13048
9336 msgid "This <literal><Location></literal> block is not yet complete, and will not do anything useful. It's merely telling Apache that whenever authorization is required, Apache should harvest a username and password from the Subversion client. What's missing here, however, are directives that tell Apache <emphasis>which</emphasis> sorts of client requests require authorization. Wherever authorization is required, Apache will demand authentication as well. The simplest thing to do is protect all requests. Adding <literal>Require valid-user</literal> tells Apache that all requests require an authenticated user:"
9340 #: ../source/book.xml:13060
9342 msgid "\n<Location /svn>\n DAV svn\n SVNParentPath /usr/local/svn\n AuthType Basic\n AuthName \"Subversion repository\"\n AuthUserFile /etc/svn-auth-file\n Require valid-user\n</Location>\n"
9346 #: ../source/book.xml:13070
9347 msgid "Be sure to read the next section (<xref linkend=\"svn.serverconfig.httpd.authz\"/>) for more detail on the <literal>Require</literal> directive and other ways to set authorization policies."
9351 #: ../source/book.xml:13081
9352 msgid "While self-signed server certificates are still vulnerable to a <quote>man in the middle</quote> attack, such an attack is much more difficult for a casual observer to pull off, compared to sniffing unprotected passwords."
9356 #: ../source/book.xml:13073
9357 msgid "One word of warning: HTTP Basic Auth passwords pass in very nearly plain-text over the network, and thus are extremely insecure. If you're worried about password snooping, it may be best to use some sort of SSL encryption, so that clients authenticate via <literal>https://</literal> instead of <literal>http://</literal>; at a bare minimum, you can configure Apache to use a self-signed server certificate. <placeholder-1/> Consult Apache's documentation (and OpenSSL documentation) about how to do that."
9361 #: ../source/book.xml:13092
9362 msgid "SSL Certificate Management"
9366 #: ../source/book.xml:13094
9367 msgid "Businesses that need to expose their repositories for access outside the company firewall should be conscious of the possibility that unauthorized parties could be <quote>sniffing</quote> their network traffic. SSL makes that kind of unwanted attention less likely to result in sensitive data leaks."
9371 #: ../source/book.xml:13100
9372 msgid "If a Subversion client is compiled to use OpenSSL, then it gains the ability to speak to an Apache server via <literal>https://</literal> URLs. The Neon library used by the Subversion client is not only able to verify server certificates, but can also supply client certificates when challenged. When the client and server have exchanged SSL certificates and successfully authenticated one another, all further communication is encrypted via a session key."
9376 #: ../source/book.xml:13108
9377 msgid "It's beyond the scope of this book to describe how to generate client and server certificates, and how to configure Apache to use them. Many other books, including Apache's own documentation, describe this task. But what <emphasis>can</emphasis> be covered here is how to manage server and client certificates from an ordinary Subversion client."
9381 #: ../source/book.xml:13115
9382 msgid "When speaking to Apache via <literal>https://</literal>, a Subversion client can receive two different types of information:"
9386 #: ../source/book.xml:13120
9387 msgid "a server certificate"
9391 #: ../source/book.xml:13123
9392 msgid "a demand for a client certificate"
9396 #: ../source/book.xml:13126
9397 msgid "If the client receives a server certificate, it needs to verify that it trusts the certificate: is the server really who it claims to be? The OpenSSL library does this by examining the signer of the server certificate, or <firstterm>certifying authority</firstterm> (CA). If OpenSSL is unable to automatically trust the CA, or if some other problem occurs (such as an expired certificate or hostname mismatch), the Subversion command-line client will ask you whether you want to trust the server certificate anyway:"
9401 #: ../source/book.xml:13136
9403 msgid "\n$ svn list https://host.example.com/repos/project\n\nError validating server certificate for 'https://host.example.com:443':\n - The certificate is not issued by a trusted authority. Use the\n fingerprint to validate the certificate manually!\nCertificate information:\n - Hostname: host.example.com\n - Valid: from Jan 30 19:23:56 2004 GMT until Jan 30 19:23:56 2006 GMT\n - Issuer: CA, example.com, Sometown, California, US\n - Fingerprint: 7d:e1:a9:34:33:39:ba:6a:e9:a5:c4:22:98:7b:76:5c:92:a0:9c:7b\n\n(R)eject, accept (t)emporarily or accept (p)ermanently?\n"
9407 #: ../source/book.xml:13150
9408 msgid "This dialogue should look familiar; it's essentially the same question you've probably seen coming from your web browser (which is just another HTTP client like Subversion). If you choose the (p)ermanent option, the server certificate will be cached in your private run-time <filename>auth/</filename> area in just the same way your username and password are cached (see <xref linkend=\"svn.serverconfig.netmodel.credcache\"/>). If cached, Subversion will automatically trust this certificate in future negotiations."
9412 #: ../source/book.xml:13159
9413 msgid "Your run-time <filename>servers</filename> file also gives you the ability to make your Subversion client automatically trust specific CAs, either globally or on a per-host basis. Simply set the <literal>ssl-authority-files</literal> variable to a semicolon-separated list of PEM-encoded CA certificates:"
9417 #: ../source/book.xml:13165
9419 msgid "\n[global]\nssl-authority-files = /path/to/CAcert1.pem;/path/to/CAcert2.pem\n"
9423 #: ../source/book.xml:13169
9424 msgid "Many OpenSSL installations also have a pre-defined set of <quote>default</quote> CAs that are nearly universally trusted. To make the Subversion client automatically trust these standard authorities, set the <literal>ssl-trust-default-ca</literal> variable to <literal>true</literal>."
9428 #: ../source/book.xml:13175
9429 msgid "When talking to Apache, a Subversion client might also receive a challenge for a client certificate. Apache is asking the client to identify itself: is the client really who it says it is? If all goes correctly, the Subversion client sends back a private certificate signed by a CA that Apache trusts. A client certificate is usually stored on disk in encrypted format, protected by a local password. When Subversion receives this challenge, it will ask you for both a path to the certificate and the password which protects it:"
9433 #: ../source/book.xml:13185
9435 msgid "\n$ svn list https://host.example.com/repos/project\n\nAuthentication realm: https://host.example.com:443\nClient certificate filename: /path/to/my/cert.p12\nPassphrase for '/path/to/my/cert.p12': ********\n…\n"
9439 #: ../source/book.xml:13193
9440 msgid "Notice that the client certificate is a <quote>p12</quote> file. To use a client certificate with Subversion, it must be in PKCS#12 format, which is a portable standard. Most web browsers are already able to import and export certificates in that format. Another option is to use the OpenSSL command-line tools to convert existing certificates into PKCS#12."
9444 #: ../source/book.xml:13200
9445 msgid "Again, the runtime <filename>servers</filename> file allows you to automate this challenge on a per-host basis. Either or both pieces of information can be described in runtime variables:"
9449 #: ../source/book.xml:13204
9451 msgid "\n[groups]\nexamplehost = host.example.com\n\n[examplehost]\nssl-client-cert-file = /path/to/my/cert.p12\nssl-client-cert-password = somepassword\n"
9455 #: ../source/book.xml:13217
9456 msgid "More security-conscious folk might not want to store the client certificate password in the runtime <filename>servers</filename> file."
9460 #: ../source/book.xml:13212
9461 msgid "Once you've set the <literal>ssl-client-cert-file</literal> and <literal>ssl-client-cert-password</literal> variables, the Subversion client can automatically respond to a client certificate challenge without prompting you. <placeholder-1/>"
9465 #: ../source/book.xml:13226
9466 msgid "Authorization Options"
9470 #: ../source/book.xml:13228
9471 msgid "At this point, you've configured authentication, but not authorization. Apache is able to challenge clients and confirm identities, but it has not been told how to allow or restrict access to the clients bearing those identities. This section describes two strategies for controlling access to your repositories."
9475 #: ../source/book.xml:13237
9476 msgid "Blanket Access Control"
9480 #: ../source/book.xml:13239
9481 msgid "The simplest form of access control is to authorize certain users for either read-only access to a repository, or read/write access to a repository."
9485 #: ../source/book.xml:13242
9486 msgid "You can restrict access on all repository operations by adding the <literal>Require valid-user</literal> directive to your <literal><Location></literal> block. Using our previous example, this would mean that only clients that claimed to be either <literal>harry</literal> or <literal>sally</literal>, and provided the correct password for their respective username, would be allowed to do anything with the Subversion repository:"
9490 #: ../source/book.xml:13250
9492 msgid "\n<Location /svn>\n DAV svn\n SVNParentPath /usr/local/svn\n\n # how to authenticate a user\n AuthType Basic\n AuthName \"Subversion repository\"\n AuthUserFile /path/to/users/file\n\n # only authenticated users may access the repository\n Require valid-user\n</Location>\n"
9496 #: ../source/book.xml:13264
9497 msgid "Sometimes you don't need to run such a tight ship. For example, Subversion's own source code repository at <uri href=\"http://svn.collab.net/repos/svn\">http://svn.collab.net/repos/svn</uri> allows anyone in the world to perform read-only repository tasks (like checking out working copies and browsing the repository with a web browser), but restricts all write operations to authenticated users. To do this type of selective restriction, you can use the <literal>Limit</literal> and <literal>LimitExcept</literal> configuration directives. Like the <literal>Location</literal> directive, these blocks have starting and ending tags, and you would nest them inside your <literal><Location></literal> block."
9501 #: ../source/book.xml:13277
9502 msgid "The parameters present on the <literal>Limit</literal> and <literal>LimitExcept</literal> directives are HTTP request types that are affected by that block. For example, if you wanted to disallow all access to your repository except the currently supported read-only operations, you would use the <literal>LimitExcept</literal> directive, passing the <literal>GET</literal>, <literal>PROPFIND</literal>, <literal>OPTIONS</literal>, and <literal>REPORT</literal> request type parameters. Then the previously mentioned <literal>Require valid-user</literal> directive would be placed inside the <literal><LimitExcept></literal> block instead of just inside the <literal><Location></literal> block."
9506 #: ../source/book.xml:13290
9508 msgid "\n<Location /svn>\n DAV svn\n SVNParentPath /usr/local/svn\n\n # how to authenticate a user\n AuthType Basic\n AuthName \"Subversion repository\"\n AuthUserFile /path/to/users/file\n\n # For any operations other than these, require an authenticated user.\n <LimitExcept GET PROPFIND OPTIONS REPORT>\n Require valid-user\n </LimitExcept>\n</Location>\n"
9512 #: ../source/book.xml:13306
9513 msgid "These are only a few simple examples. For more in-depth information about Apache access control and the <literal>Require</literal> directive, take a look at the <literal>Security</literal> section of the Apache documentation's tutorials collection at <uri href=\"http://httpd.apache.org/docs-2.0/misc/tutorials.html\">http://httpd.apache.org/docs-2.0/misc/tutorials.html</uri>."
9517 #: ../source/book.xml:13315
9518 msgid "Per-Directory Access Control"
9522 #: ../source/book.xml:13317
9523 msgid "It's possible to set up finer-grained permissions using a second Apache httpd module, <command>mod_authz_svn</command>. This module grabs the various opaque URLs passing from client to server, asks <command>mod_dav_svn</command> to decode them, and then possibly vetoes requests based on access policies defined in a configuration file."
9527 #: ../source/book.xml:13324
9528 msgid "If you've built Subversion from source code, <command>mod_authz_svn</command> is automatically built and installed alongside <command>mod_dav_svn</command>. Many binary distributions install it automatically as well. To verify that it's installed correctly, make sure it comes right after <command>mod_dav_svn</command>'s <literal>LoadModule</literal> directive in <filename>httpd.conf</filename>:"
9532 #: ../source/book.xml:13332
9534 msgid "\nLoadModule dav_module modules/mod_dav.so\nLoadModule dav_svn_module modules/mod_dav_svn.so\nLoadModule authz_svn_module modules/mod_authz_svn.so\n"
9538 #: ../source/book.xml:13337
9539 msgid "To activate this module, you need to configure your <literal>Location</literal> block to use the <literal>AuthzSVNAccessFile</literal> directive, which specifies a file containing the permissions policy for paths within your repositories. (In a moment, we'll discuss the format of that file.)"
9543 #: ../source/book.xml:13343
9544 msgid "Apache is flexible, so you have the option to configure your block in one of three general patterns. To begin, choose one of these basic configuration patterns. (The examples below are very simple; look at Apache's own documentation for much more detail on Apache authentication and authorization options.)"
9548 #: ../source/book.xml:13349
9549 msgid "The simplest block is to allow open access to everyone. In this scenario, Apache never sends authentication challenges, so all users are treated as <quote>anonymous</quote>."
9553 #: ../source/book.xml:13355
9554 msgid "A sample configuration for anonymous access."
9558 #: ../source/book.xml:13357
9560 msgid "\n<Location /repos>\n DAV svn\n SVNParentPath /usr/local/svn\n\n # our access control policy\n AuthzSVNAccessFile /path/to/access/file\n</Location>\n "
9564 #: ../source/book.xml:13367
9565 msgid "On the opposite end of the paranoia scale, you can configure your block to demand authentication from everyone. All clients must supply credentials to identify themselves. Your block unconditionally requires authentication via the <literal>Require valid-user</literal> directive, and defines a means to authenticate."
9569 #: ../source/book.xml:13375
9570 msgid "A sample configuration for authenticated access."
9574 #: ../source/book.xml:13377
9576 msgid "\n<Location /repos>\n DAV svn\n SVNParentPath /usr/local/svn\n\n # our access control policy\n AuthzSVNAccessFile /path/to/access/file\n\n # only authenticated users may access the repository\n Require valid-user\n\n # how to authenticate a user\n AuthType Basic\n AuthName \"Subversion repository\"\n AuthUserFile /path/to/users/file\n</Location>\n "
9580 #: ../source/book.xml:13395
9581 msgid "A third very popular pattern is to allow a combination of authenticated and anonymous access. For example, many administrators want to allow anonymous users to read certain repository directories, but want only authenticated users to read (or write) more sensitive areas. In this setup, all users start out accessing the repository anonymously. If your access control policy demands a real username at any point, Apache will demand authentication from the client. To do this, you use both the <literal>Satisfy Any</literal> and <literal>Require valid-user</literal> directives together."
9585 #: ../source/book.xml:13408
9586 msgid "A sample configuration for mixed authenticated/anonymous access."
9590 #: ../source/book.xml:13411
9592 msgid "\n<Location /repos>\n DAV svn\n SVNParentPath /usr/local/svn\n\n # our access control policy\n AuthzSVNAccessFile /path/to/access/file\n\n # try anonymous access first, resort to real\n # authentication if necessary.\n Satisfy Any\n Require valid-user\n\n # how to authenticate a user\n AuthType Basic\n AuthName \"Subversion repository\"\n AuthUserFile /path/to/users/file\n</Location>\n "
9596 #: ../source/book.xml:13431
9597 msgid "Once you've settled on one of these three basic <filename>httpd.conf</filename> templates, you need to create your file containing access rules for particular paths within the repository. This is described in <xref linkend=\"svn.serverconfig.pathbasedauthz\"/>."
9601 #: ../source/book.xml:13440
9602 msgid "Disabling Path-based Checks"
9606 #: ../source/book.xml:13442
9607 msgid "The <command>mod_dav_svn</command> module goes through a lot of work to make sure that data you've marked <quote>unreadable</quote> doesn't get accidentally leaked. This means that it needs to closely monitor all of the paths and file-contents returned by commands like <command>svn checkout</command> or <command>svn update</command> commands. If these commands encounter a path that isn't readable according to some authorization policy, then the path is typically omitted altogether. In the case of history or rename tracing—e.g. running a command like <command>svn cat -r OLD foo.c</command> on a file that was renamed long ago—the rename tracking will simply halt if one of the object's former names is determined to be read-restricted."
9611 #: ../source/book.xml:13456
9612 msgid "All of this path-checking can sometimes be quite expensive, especially in the case of <command>svn log</command>. When retrieving a list of revisions, the server looks at every changed path in each revision and checks it for readability. If an unreadable path is discovered, then it's omitted from the list of the revision's changed paths (normally seen with the <option>--verbose</option> option), and the whole log message is suppressed. Needless to say, this can be time-consuming on revisions that affect a large number of files. This is the cost of security: even if you haven't configured a module like <command>mod_authz_svn</command> at all, the <command>mod_dav_svn</command> module is still asking Apache <command>httpd</command> to run authorization checks on every path. The <command>mod_dav_svn</command> module has no idea what authorization modules have been installed, so all it can do is ask Apache to invoke whatever might be present."
9616 #: ../source/book.xml:13474
9617 msgid "On the other hand, there's also an escape-hatch of sorts, one which allows you to trade security features for speed. If you're not enforcing any sort of per-directory authorization (i.e. not using <command>mod_authz_svn</command> or similar module), then you can disable all of this path-checking. In your <filename>httpd.conf</filename> file, use the <literal>SVNPathAuthz</literal> directive:"
9621 #: ../source/book.xml:13484
9622 msgid "Disabling path checks altogether"
9626 #: ../source/book.xml:13486
9628 msgid "\n<Location /repos>\n DAV svn\n SVNParentPath /usr/local/svn\n\n SVNPathAuthz off\n</Location>\n "
9632 #: ../source/book.xml:13495
9633 msgid "The <literal>SVNPathAuthz</literal> directive is <quote>on</quote> by default. When set <quote>off</quote>, all path-based authorization checking is disabled; <command>mod_dav_svn</command> stops invoking authorization checks on every path it discovers."
9637 #: ../source/book.xml:13505
9638 msgid "Extra Goodies"
9642 #: ../source/book.xml:13507
9643 msgid "We've covered most of the authentication and authorization options for Apache and mod_dav_svn. But there are a few other nice features that Apache provides."
9647 #: ../source/book.xml:13513
9648 msgid "Repository Browsing"
9652 #: ../source/book.xml:13515
9653 msgid "One of the most useful benefits of an Apache/WebDAV configuration for your Subversion repository is that the youngest revisions of your versioned files and directories are immediately available for viewing via a regular web browser. Since Subversion uses URLs to identify versioned resources, those URLs used for HTTP-based repository access can be typed directly into a Web browser. Your browser will issue an HTTP <literal>GET</literal> request for that URL, and based on whether that URL represents a versioned directory or file, mod_dav_svn will respond with a directory listing or with file contents."
9657 #: ../source/book.xml:13526
9658 msgid "Since the URLs do not contain any information about which version of the resource you wish to see, mod_dav_svn will always answer with the youngest version. This functionality has the wonderful side-effect that you can pass around Subversion URLs to your peers as references to documents, and those URLs will always point at the latest manifestation of that document. Of course, you can even use the URLs as hyperlinks from other web sites, too."
9662 #: ../source/book.xml:13536
9663 msgid "Can I view older revisions?"
9667 #: ../source/book.xml:13538
9668 msgid "With an ordinary web browser? In one word: nope. At least, not with <command>mod_dav_svn</command> as your only tool."
9672 #: ../source/book.xml:13541
9673 msgid "Your web browser only speaks ordinary HTTP. That means it only knows how to GET public URLs, which represent the latest versions of files and directories. According to the WebDAV/DeltaV specification, each server defines a private URL syntax for older versions of resources, and that syntax is opaque to clients. To find an older version of a file, a client must follow a specific procedure to <quote>discover</quote> the proper URL; the procedure involves issuing a series of WebDAV PROPFIND requests and understanding DeltaV concepts. This is something your web browser simply can't do."
9677 #: ../source/book.xml:13562
9678 msgid "Back then, it was called <quote>ViewCVS</quote>."
9682 #: ../source/book.xml:13552
9683 msgid "So to answer the question, one obvious way to see older revisions of files and directories is by passing the <option>--revision (-r)</option> argument to the <command>svn list</command> and <command>svn cat</command> commands. To browse old revisions with your web browser, however, you can use third-party software. A good example of this is ViewVC (<uri href=\"http://viewvc.tigris.org/\">http://viewvc.tigris.org/</uri>). ViewVC was originally written to display CVS repositories through the web, <placeholder-1/> and the latest releases are able to understand Subversion repositories as well."
9687 #: ../source/book.xml:13568
9688 msgid "Proper MIME Type"
9692 #: ../source/book.xml:13570
9693 msgid "When browsing a Subversion repository, the web browser gets a clue about how to render a file's contents by looking at the <literal>Content-Type:</literal> header returned in Apache's response to the HTTP <literal>GET</literal> request. The value of this header is some sort of MIME type. By default, Apache will tell the web browsers that all repository files are of the <quote>default</quote> MIME type, typically <literal>text/plain</literal>. This can be frustrating, however, if a user wishes repository files to render as something more meaningful—for example, it might be nice to have a <filename>foo.html</filename> file in the repository actually render as HTML when browsing."
9697 #: ../source/book.xml:13584
9698 msgid "To make this happen, you only need to make sure that your files have the proper <literal>svn:mime-type</literal> set. This is discussed in more detail in <xref linkend=\"svn.advanced.props.special.mime-type\"/>, and you can even configure your client to automatically attach proper <literal>svn:mime-type</literal> properties to files entering the repository for the first time; see <xref linkend=\"svn.advanced.props.auto\"/>."
9702 #: ../source/book.xml:13593
9703 msgid "So in our example, if one were to set the <literal>svn:mime-type</literal> property to <literal>text/html</literal> on file <filename>foo.html</filename>, then Apache would properly tell your web browser to render the file as HTML. One could also attach proper <literal>image/*</literal> mime-type properties to images, and by doing this, ultimately get an entire web site to be viewable directly from a repository! There's generally no problem with doing this, as long as the website doesn't contain any dynamically-generated content."
9707 #: ../source/book.xml:13608
9708 msgid "Customizing the Look"
9712 #: ../source/book.xml:13610
9713 msgid "You generally will get more use out of URLs to versioned files—after all, that's where the interesting content tends to lie. But you might have occasion to browse a Subversion directory listing, where you'll quickly note that the generated HTML used to display that listing is very basic, and certainly not intended to be aesthetically pleasing (or even interesting). To enable customization of these directory displays, Subversion provides an XML index feature. A single <literal>SVNIndexXSLT</literal> directive in your repository's <literal>Location</literal> block of <filename>httpd.conf</filename> will instruct mod_dav_svn to generate XML output when displaying a directory listing, and to reference the XSLT stylesheet of your choice:"
9717 #: ../source/book.xml:13625
9719 msgid "\n<Location /svn>\n DAV svn\n SVNParentPath /usr/local/svn\n SVNIndexXSLT \"/svnindex.xsl\"\n …\n</Location>\n"
9723 #: ../source/book.xml:13633
9724 msgid "Using the <literal>SVNIndexXSLT</literal> directive and a creative XSLT stylesheet, you can make your directory listings match the color schemes and imagery used in other parts of your website. Or, if you'd prefer, you can use the sample stylesheets provided in the Subversion source distribution's <filename>tools/xslt/</filename> directory. Keep in mind that the path provided to the <literal>SVNIndexXSLT</literal> directory is actually a URL path—browsers need to be able to read your stylesheets in order to make use of them!"
9728 #: ../source/book.xml:13646
9729 msgid "Listing Repositories"
9733 #: ../source/book.xml:13648
9734 msgid "If you're serving a collection of repositories from a single URL via the <literal>SVNParentPath</literal> directive, then it's also possible to have Apache display all available repositories to a web browser. Just activate the <literal>SVNListParentPath</literal> directive:"
9738 #: ../source/book.xml:13654
9740 msgid "\n<Location /svn>\n DAV svn\n SVNParentPath /usr/local/svn\n SVNListParentPath on\n …\n</Location>\n"
9744 #: ../source/book.xml:13662
9745 msgid "If a user now points her web browser to the URL <literal>http://host.example.com/svn/</literal>, she'll see list of all Subversion repositories sitting in <filename>/usr/local/svn</filename>. Obviously, this can be a security problem, so this feature is turned off by default."
9749 #: ../source/book.xml:13673
9750 msgid "Apache Logging"
9754 #: ../source/book.xml:13675
9755 msgid "Because Apache is an HTTP server at heart, it contains fantastically flexible logging features. It's beyond the scope of this book to discuss all ways logging can be configured, but we should point out that even the most generic <filename>httpd.conf</filename> file will cause Apache to produce two logs: <filename>error_log</filename> and <filename>access_log</filename>. These logs may appear in different places, but are typically created in the logging area of your Apache installation. (On Unix, they often live in <filename>/usr/local/apache2/logs/</filename>.)"
9759 #: ../source/book.xml:13687
9760 msgid "The <filename>error_log</filename> describes any internal errors that Apache runs into as it works. The <filename>access_log</filename> file records every incoming HTTP request received by Apache. This makes it easy to see, for example, which IP addresses Subversion clients are coming from, how often particular clients use the server, which users are authenticating properly, and which requests succeed or fail."
9764 #: ../source/book.xml:13695
9765 msgid "Unfortunately, because HTTP is a stateless protocol, even the simplest Subversion client operation generates multiple network requests. It's very difficult to look at the <filename>access_log</filename> and deduce what the client was doing—most operations look like a series of cryptic <literal>PROPPATCH</literal>, <literal>GET</literal>, <literal>PUT</literal>, and <literal>REPORT</literal> requests. To make things worse, many client operations send nearly-identical series of requests, so it's even harder to tell them apart."
9769 #: ../source/book.xml:13705
9770 msgid "<literal>mod_dav_svn</literal>, however, can come to your aid. By activating an <quote>operational logging</quote> feature, you can ask <literal>mod_dav_svn</literal> to create a separate log file describing what sort of high-level operations your clients are performing."
9774 #: ../source/book.xml:13711
9775 msgid "To do this, you need to make use of Apache's <literal>CustomLog</literal> directive (which is explained in more detail in Apache's own documentation). Be sure to invoke this directive <emphasis>outside</emphasis> of your Subversion <literal>Location</literal> block:"
9779 #: ../source/book.xml:13717
9781 msgid "\n<Location /svn>\n DAV svn\n …\n</Location>\n\nCustomLog logs/svn_logfile \"%t %u %{SVN-ACTION}e\" env=SVN-ACTION\n"
9785 #: ../source/book.xml:13725
9786 msgid "In this example, we're asking Apache to create a special logfile <filename>svn_logfile</filename> in the standard Apache <filename>logs</filename> directory. The <literal>%t</literal> and <literal>%u</literal> variables are replaced by the time and username of the request, respectively. The really important part are the two instances of <literal>SVN-ACTION</literal>. When Apache sees that variable, it substitutes the value of the <literal>SVN-ACTION</literal> environment variable, which is automatically set by <literal>mod_dav_svn</literal> whenever it detects a high-level client action."
9790 #: ../source/book.xml:13736
9791 msgid "So instead of having to interpret a traditional <filename>access_log</filename> like this:"
9795 #: ../source/book.xml:13739
9797 msgid "\n[26/Jan/2007:22:25:29 -0600] \"PROPFIND /svn/calc/!svn/vcc/default HTTP/1.1\" 207 398\n[26/Jan/2007:22:25:29 -0600] \"PROPFIND /svn/calc/!svn/bln/59 HTTP/1.1\" 207 449\n[26/Jan/2007:22:25:29 -0600] \"PROPFIND /svn/calc HTTP/1.1\" 207 647\n[26/Jan/2007:22:25:29 -0600] \"REPORT /svn/calc/!svn/vcc/default HTTP/1.1\" 200 607\n[26/Jan/2007:22:25:31 -0600] \"OPTIONS /svn/calc HTTP/1.1\" 200 188\n[26/Jan/2007:22:25:31 -0600] \"MKACTIVITY /svn/calc/!svn/act/e6035ef7-5df0-4ac0-b811-4be7c823f998 HTTP/1.1\" 201 227\n…\n"
9801 #: ../source/book.xml:13748
9802 msgid "… you can instead peruse a much more intelligible <filename>svn_logfile</filename> like this:"
9806 #: ../source/book.xml:13750
9808 msgid "\n[26/Jan/2007:22:24:20 -0600] - list-dir '/'\n[26/Jan/2007:22:24:27 -0600] - update '/'\n[26/Jan/2007:22:25:29 -0600] - remote-status '/'\n[26/Jan/2007:22:25:31 -0600] sally commit r60\n"
9812 #: ../source/book.xml:13760
9813 msgid "Other Features"
9817 #: ../source/book.xml:13762
9818 msgid "Several of the features already provided by Apache in its role as a robust Web server can be leveraged for increased functionality or security in Subversion as well. Subversion communicates with Apache using Neon, which is a generic HTTP/WebDAV library with support for such mechanisms as SSL (the Secure Socket Layer, discussed earlier). If your Subversion client is built to support SSL, then it can access your Apache server using <literal>https://</literal>."
9822 #: ../source/book.xml:13771
9823 msgid "Equally useful are other features of the Apache and Subversion relationship, such as the ability to specify a custom port (instead of the default HTTP port 80) or a virtual domain name by which the Subversion repository should be accessed, or the ability to access the repository through an HTTP proxy. These things are all supported by Neon, so Subversion gets that support for free."
9827 #: ../source/book.xml:13778
9828 msgid "Finally, because <command>mod_dav_svn</command> is speaking a subset of the WebDAV/DeltaV protocol, it's possible to access the repository via third-party DAV clients. Most modern operating systems (Win32, OS X, and Linux) have the built-in ability to mount a DAV server as a standard network share. This is a complicated topic; for details, read <xref linkend=\"svn.webdav\"/>."
9832 #: ../source/book.xml:13793
9833 msgid "Path-Based Authorization"
9837 #: ../source/book.xml:13795
9838 msgid "Both Apache and <command>svnserve</command> are capable of granting (or denying) permissions to users. Typically this is done over the entire repository: a user can read the repository (or not), and she can write to the repository (or not). It's also possible, however, to define finer-grained access rules. One set of users may have permission to write to a certain directory in the repository, but not others; another directory might not even be readable by all but a few special people."
9842 #: ../source/book.xml:13804
9843 msgid "Both servers use a common file format to describe these path-based access rules. In the case of Apache, one needs to load the <command>mod_authz_svn</command> module and then add the <literal>AuthzSVNAccessFile</literal> directive (within the <filename>httpd.conf</filename> file) pointing to your own rules-file. (For a full explanation, see <xref linkend=\"svn.serverconfig.httpd.authz.perdir\"/>.) If you're using <command>svnserve</command>, then you need to make the <literal>authz-db</literal> variable (within <filename>svnserve.conf</filename>) point to your rules-file."
9847 #: ../source/book.xml:13817
9848 msgid "Do you really need path-based access control?"
9852 #: ../source/book.xml:13819
9853 msgid "A lot of administrators setting up Subversion for the first time tend to jump into path-based access control without giving it a lot of thought. The administrator usually knows which teams of people are working on which projects, so it's easy to jump in and grant certain teams access to certain directories and not others. It seems like a natural thing, and it appeases the administrator's desire to maintain tight control of the repository."
9857 #: ../source/book.xml:13827
9858 msgid "Note, though, that there are often invisible (and visible!) costs associated with this feature. In the visible category, the server needs to do a lot more work to ensure that the user has the right to read or write each specific path; in certain situations, there's very noticeable performance loss. In the invisible category, consider the culture you're creating. Most of the time, while certain users <emphasis>shouldn't</emphasis> be committing changes to certain parts of the repository, that social contract doesn't need to be technologically enforced. Teams can sometimes spontaneously collaborate with each other; someone may want to help someone else out by committing to an area she doesn't normally work on. By preventing this sort of thing at the server level, you're setting up barriers to unexpected collaboration. You're also creating a bunch of rules that need to be maintained as projects develop, new users are added, and so on. It's a bunch of extra work to maintain."
9862 #: ../source/book.xml:13845
9863 msgid "Remember that this is a version control system! Even if somebody accidentally commits a change to something they shouldn't, it's easy to undo the change. And if a user commits to the wrong place with deliberate malice, then it's a social problem anyway, and that the problem needs to be dealt with outside of Subversion."
9867 #: ../source/book.xml:13857
9868 msgid "A common theme in this book!"
9872 #: ../source/book.xml:13851
9873 msgid "So before you begin restricting users' access rights, ask yourself if there's a real, honest need for this, or if it's just something that <quote>sounds good</quote> to an administrator. Decide whether it's worth sacrificing some server speed for, and remember that there's very little risk involved; it's bad to become dependent on technology as a crutch for social problems.<placeholder-1/>."
9877 #: ../source/book.xml:13859
9878 msgid "As an example to ponder, consider that the Subversion project itself has always had a notion of who is allowed to commit where, but it's always been enforced socially. This is a good model of community trust, especially for open-source projects. Of course, sometimes there <emphasis>are</emphasis> truly legitimate needs for path-based access control; within corporations, for example, certain types of data really can be sensitive, and access needs to be genuinely restricted to small groups of people."
9882 #: ../source/book.xml:13869
9883 msgid "Once your server knows where to find your rules-file, it's time to define the rules."
9887 #: ../source/book.xml:13871
9888 msgid "The syntax of the file is the same familiar one used by <command>svnserve.conf</command> and the runtime configuration files. Lines that start with a hash (<literal>#</literal>) are ignored. In its simplest form, each section names a repository and path within it, and the authenticated usernames are the option names within each section. The value of each option describes the user's level of access to the repository path: either <literal>r</literal> (read-only) or <literal>rw</literal> (read-write). If the user is not mentioned at all, no access is allowed."
9892 #: ../source/book.xml:13882
9893 msgid "To be more specific: the value of the section-names are either of the form <literal>[repos-name:path]</literal> or the form <literal>[path]</literal>. If you're using the <literal>SVNParentPath</literal> directive, then it's important to specify the repository names in your sections. If you omit them, then a section like <literal>[/some/dir]</literal> will match the path <filename>/some/dir</filename> in <emphasis>every</emphasis> repository. If you're using the <literal>SVNPath</literal> directive, however, then it's fine to only define paths in your sections—after all, there's only one repository."
9897 #: ../source/book.xml:13893
9899 msgid "\n[calc:/branches/calc/bug-142]\nharry = rw\nsally = r\n"
9903 #: ../source/book.xml:13898
9904 msgid "In this first example, the user <literal>harry</literal> has full read and write access on the <filename>/branches/calc/bug-142</filename> directory in the <literal>calc</literal> repository, but the user <literal>sally</literal> has read-only access. Any other users are blocked from accessing this directory."
9908 #: ../source/book.xml:13904
9909 msgid "Of course, permissions are inherited from parent to child directory. That means that we can specify a subdirectory with a different access policy for Sally:"
9913 #: ../source/book.xml:13907
9915 msgid "\n[calc:/branches/calc/bug-142]\nharry = rw\nsally = r\n\n# give sally write access only to the 'testing' subdir\n[calc:/branches/calc/bug-142/testing]\nsally = rw\n"
9919 #: ../source/book.xml:13916
9920 msgid "Now Sally can write to the <filename>testing</filename> subdirectory of the branch, but can still only read other parts. Harry, meanwhile, continues to have complete read-write access to the whole branch."
9924 #: ../source/book.xml:13920
9925 msgid "It's also possible to explicitly deny permission to someone via inheritance rules, by setting the username variable to nothing:"
9929 #: ../source/book.xml:13923
9931 msgid "\n[calc:/branches/calc/bug-142]\nharry = rw\nsally = r\n\n[calc:/branches/calc/bug-142/secret]\nharry =\n"
9935 #: ../source/book.xml:13931
9936 msgid "In this example, Harry has read-write access to the entire <filename>bug-142</filename> tree, but has absolutely no access at all to the <filename>secret</filename> subdirectory within it."
9940 #: ../source/book.xml:13935
9941 msgid "The thing to remember is that the most specific path always matches first. The server tries to match the path itself, and then the parent of the path, then the parent of that, and so on. The net effect is that mentioning a specific path in the accessfile will always override any permissions inherited from parent directories."
9945 #: ../source/book.xml:13941
9946 msgid "By default, nobody has any access to the repository at all. That means that if you're starting with an empty file, you'll probably want to give at least read permission to all users at the root of the repository. You can do this by using the asterisk variable (<literal>*</literal>), which means <quote>all users</quote>:"
9950 #: ../source/book.xml:13947
9952 msgid "\n[/]\n* = r\n"
9956 #: ../source/book.xml:13951
9957 msgid "This is a common setup; notice that there's no repository name mentioned in the section name. This makes all repositories world readable to all users. Once all users have read-access to the repositories, you can give explicit <literal>rw</literal> permission to certain users on specific subdirectories within specific repositories."
9961 #: ../source/book.xml:13957
9962 msgid "The asterisk variable (<literal>*</literal>) is also worth special mention here: it's the <emphasis>only</emphasis> pattern which matches an anonymous user. If you've configured your server block to allow a mixture of anonymous and authenticated access, all users start out accessing anonymously. The server looks for a <literal>*</literal> value defined for the path being accessed; if it can't find one, then it demands real authentication from the client."
9966 #: ../source/book.xml:13966
9967 msgid "The access file also allows you to define whole groups of users, much like the Unix <filename>/etc/group</filename> file:"
9971 #: ../source/book.xml:13969
9973 msgid "\n[groups]\ncalc-developers = harry, sally, joe\npaint-developers = frank, sally, jane\neveryone = harry, sally, joe, frank, sally, jane\n"
9977 #: ../source/book.xml:13975
9978 msgid "Groups can be granted access control just like users. Distinguish them with an <quote>at</quote> (<literal>@</literal>) prefix:"
9982 #: ../source/book.xml:13978
9984 msgid "\n[calc:/projects/calc]\n@calc-developers = rw\n\n[paint:/projects/paint]\n@paint-developers = rw\njane = r\n"
9988 #: ../source/book.xml:13986
9989 msgid "Groups can also be defined to contain other groups:"
9993 #: ../source/book.xml:13987
9995 msgid "\n[groups]\ncalc-developers = harry, sally, joe\npaint-developers = frank, sally, jane\neveryone = @calc-developers, @paint-developers\n"
9999 #: ../source/book.xml:13998
10000 msgid "Partial Readability and Checkouts"
10004 #: ../source/book.xml:14000
10005 msgid "If you're using Apache as your Subversion server and have made certain subdirectories of your repository unreadable to certain users, then you need to be aware of a possible non-optimal behavior with <command>svn checkout</command>."
10009 #: ../source/book.xml:14005
10010 msgid "When the client requests a checkout or update over HTTP, it makes a single server request, and receives a single (often large) server response. When the server receives the request, that is the <emphasis>only</emphasis> opportunity Apache has to demand user authentication. This has some odd side-effects. For example, if a certain subdirectory of the repository is only readable by user Sally, and user Harry checks out a parent directory, his client will respond to the initial authentication challenge as Harry. As the server generates the large response, there's no way it can re-send an authentication challenge when it reaches the special subdirectory; thus the subdirectory is skipped altogether, rather than asking the user to re-authenticate as Sally at the right moment. In a similar way, if the root of the repository is anonymously world-readable, then the entire checkout will be done without authentication—again, skipping the unreadable directory, rather than asking for authentication partway through."
10014 #: ../source/book.xml:14029
10015 msgid "Supporting Multiple Repository Access Methods"
10019 #: ../source/book.xml:14031
10020 msgid "You've seen how a repository can be accessed in many different ways. But is it possible—or safe—for your repository to be accessed by multiple methods simultaneously? The answer is yes, provided you use a bit of foresight."
10024 #: ../source/book.xml:14035
10025 msgid "At any given time, these processes may require read and write access to your repository:"
10029 #: ../source/book.xml:14039
10030 msgid "regular system users using a Subversion client (as themselves) to access the repository directly via <literal>file://</literal> URLs;"
10034 #: ../source/book.xml:14044
10035 msgid "regular system users connecting to SSH-spawned private <command>svnserve</command> processes (running as themselves) which access the repository;"
10039 #: ../source/book.xml:14049
10040 msgid "an <command>svnserve</command> process—either a daemon or one launched by <command>inetd</command>—running as a particular fixed user;"
10044 #: ../source/book.xml:14055
10045 msgid "an Apache <command>httpd</command> process, running as a particular fixed user."
10049 #: ../source/book.xml:14059
10050 msgid "The most common problem administrators run into is repository ownership and permissions. Does every process (or user) in the previous list have the rights to read and write the Berkeley DB files? Assuming you have a Unix-like operating system, a straightforward approach might be to place every potential repository user into a new <literal>svn</literal> group, and make the repository wholly owned by that group. But even that's not enough, because a process may write to the database files using an unfriendly umask—one that prevents access by other users."
10054 #: ../source/book.xml:14069
10055 msgid "So the next step beyond setting up a common group for repository users is to force every repository-accessing process to use a sane umask. For users accessing the repository directly, you can make the <command>svn</command> program into a wrapper script that first sets <command>umask 002</command> and then runs the real <command>svn</command> client program. You can write a similar wrapper script for the <command>svnserve</command> program, and add a <command>umask 002</command> command to Apache's own startup script, <filename>apachectl</filename>. For example:"
10059 #: ../source/book.xml:14079
10061 msgid "\n$ cat /usr/bin/svn\n\n#!/bin/sh\n\numask 002\n/usr/bin/svn-real \"$@\"\n\n"
10065 #: ../source/book.xml:14088
10066 msgid "Another common problem is often encountered on Unix-like systems. As a repository is used, Berkeley DB occasionally creates new log files to journal its actions. Even if the repository is wholly owned by the <command>svn</command> group, these newly created files won't necessarily be owned by that same group, which then creates more permissions problems for your users. A good workaround is to set the group SUID bit on the repository's <filename>db</filename> directory. This causes all newly-created log files to have the same group owner as the parent directory."
10070 #: ../source/book.xml:14098
10071 msgid "Once you've jumped through these hoops, your repository should be accessible by all the necessary processes. It may seem a bit messy and complicated, but the problems of having multiple users sharing write-access to common files are classic ones that are not often elegantly solved."
10075 #: ../source/book.xml:14103
10076 msgid "Fortunately, most repository administrators will never <emphasis>need</emphasis> to have such a complex configuration. Users who wish to access repositories that live on the same machine are not limited to using <literal>file://</literal> access URLs—they can typically contact the Apache HTTP server or <command>svnserve</command> using <literal>localhost</literal> for the server name in their <literal>http://</literal> or <literal>svn://</literal> URLs. And to maintain multiple server processes for your Subversion repositories is likely to be more of a headache than necessary. We recommend you choose the server that best meets your needs and stick with it!"
10080 #: ../source/book.xml:14117
10081 msgid "The svn+ssh:// server checklist"
10085 #: ../source/book.xml:14119
10086 msgid "It can be quite tricky to get a bunch of users with existing SSH accounts to share a repository without permissions problems. If you're confused about all the things that you (as an administrator) need to do on a Unix-like system, here's a quick checklist that resummarizes some of things discussed in this section:"
10090 #: ../source/book.xml:14127
10091 msgid "All of your SSH users need to be able to read and write to the repository, so: put all the SSH users into a single group."
10095 #: ../source/book.xml:14132
10096 msgid "Make the repository wholly owned by that group."
10100 #: ../source/book.xml:14137
10101 msgid "Set the group permissions to read/write."
10105 #: ../source/book.xml:14140
10106 msgid "Your users need to use a sane umask when accessing the repository, so: make sure that <command>svnserve</command> (<filename>/usr/bin/svnserve</filename>, or wherever it lives in <literal>$PATH</literal>) is actually a wrapper script which sets <command>umask 002</command> and executes the real <command>svnserve</command> binary."
10110 #: ../source/book.xml:14149
10111 msgid "Take similar measures when using <command>svnlook</command> and <command>svnadmin</command>. Either run them with a sane umask, or wrap them as described above."
10115 #: ../source/book.xml:14165
10116 msgid "Customizing Your Subversion Experience"
10120 #: ../source/book.xml:14167
10121 msgid "Version control can be a complex subject, as much art as science, and offering myriad ways of getting stuff done. Throughout this book you've read of the various Subversion command-line client subcommands and the options which modify their behavior. In this chapter, we'll look into still more ways to customize the way Subversion works for you—setting up the Subversion runtime configuration, using external helper applications, Subversion's interaction with the operating system's configured locale, and so on."
10125 #: ../source/book.xml:14186
10126 msgid "Runtime Configuration Area"
10130 #: ../source/book.xml:14188
10131 msgid "Subversion provides many optional behaviors that can be controlled by the user. Many of these options are of the kind that a user would wish to apply to all Subversion operations. So, rather than forcing users to remember command-line arguments for specifying these options, and to use them for every operation they perform, Subversion uses configuration files, segregated into a Subversion configuration area."
10135 #: ../source/book.xml:14195
10136 msgid "The Subversion <firstterm>configuration area</firstterm> is a two-tiered hierarchy of option names and their values. Usually, this boils down to a special directory that contains <firstterm>configuration files</firstterm> (the first tier), which are just text files in standard INI format (with <quote>sections</quote> providing the second tier). These files can be easily edited using your favorite text editor (such as Emacs or vi), and contain directives read by the client to determine which of several optional behaviors the user prefers."
10140 #: ../source/book.xml:14208
10141 msgid "Configuration Area Layout"
10145 #: ../source/book.xml:14221
10146 msgid "The <literal>APPDATA</literal> environment variable points to the <filename>Application Data</filename> area, so you can always refer to this folder as <filename>%APPDATA%\\Subversion</filename>."
10150 #: ../source/book.xml:14210
10151 msgid "The first time that the <command>svn</command> command-line client is executed, it creates a per-user configuration area. On Unix-like systems, this area appears as a directory named <filename>.subversion</filename> in the user's home directory. On Win32 systems, Subversion creates a folder named <filename>Subversion</filename>, typically inside the <filename>Application Data</filename> area of the user's profile directory (which, by the way, is usually a hidden directory). However, on this platform the exact location differs from system to system, and is dictated by the Windows registry. <placeholder-1/> We will refer to the per-user configuration area using its Unix name, <filename>.subversion</filename>."
10155 #: ../source/book.xml:14227
10156 msgid "In addition to the per-user configuration area, Subversion also recognizes the existence of a system-wide configuration area. This gives system administrators the ability to establish defaults for all users on a given machine. Note that the system-wide configuration area does not alone dictate mandatory policy—the settings in the per-user configuration area override those in the system-wide one, and command-line arguments supplied to the <command>svn</command> program have the final word on behavior. On Unix-like platforms, the system-wide configuration area is expected to be the <filename>/etc/subversion</filename> directory; on Windows machines, it looks for a <filename>Subversion</filename> directory inside the common <filename>Application Data</filename> location (again, as specified by the Windows Registry). Unlike the per-user case, the <command>svn</command> program does not attempt to create the system-wide configuration area."
10160 #: ../source/book.xml:14244
10161 msgid "The per-user configuration area currently contains three files—two configuration files (<filename>config</filename> and <filename>servers</filename>), and a <filename>README.txt</filename> file which describes the INI format. At the time of their creation, the files contain default values for each of the supported Subversion options, mostly commented out and grouped with textual descriptions about how the values for the key affect Subversion's behavior. To change a certain behavior, you need only to load the appropriate configuration file into a text editor, and modify the desired option's value. If at any time you wish to have the default configuration settings restored, you can simply remove (or rename) your configuration directory and then run some innocuous <command>svn</command> command, such as <command>svn --version</command>. A new configuration directory with the default contents will be created."
10165 #: ../source/book.xml:14260
10166 msgid "The per-user configuration area also contains a cache of authentication data. The <filename>auth</filename> directory holds a set of subdirectories that contain pieces of cached information used by Subversion's various supported authentication methods. This directory is created in such a way that only the user herself has permission to read its contents."
10170 #: ../source/book.xml:14271
10171 msgid "Configuration and the Windows Registry"
10175 #: ../source/book.xml:14273
10176 msgid "In addition to the usual INI-based configuration area, Subversion clients running on Windows platforms may also use the Windows registry to hold the configuration data. The option names and their values are the same as in the INI files. The <quote>file/section</quote> hierarchy is preserved as well, though addressed in a slightly different fashion—in this schema, files and sections are just levels in the registry key tree."
10180 #: ../source/book.xml:14281
10181 msgid "Subversion looks for system-wide configuration values under the <literal>HKEY_LOCAL_MACHINE\\Software\\Tigris.org\\Subversion</literal> key. For example, the <literal>global-ignores</literal> option, which is in the <literal>miscellany</literal> section of the <filename>config</filename> file, would be found at <literal>HKEY_LOCAL_MACHINE\\Software\\Tigris.org\\Subversion\\Config\\Miscellany\\global-ignores</literal>. Per-user configuration values should be stored under <literal>HKEY_CURRENT_USER\\Software\\Tigris.org\\Subversion</literal>."
10185 #: ../source/book.xml:14291
10186 msgid "Registry-based configuration options are parsed <emphasis>before</emphasis> their file-based counterparts, so are overridden by values found in the configuration files. In other words, Subversion looks for configuration information in the following locations on a Windows system; lower-numbered locations take precedence over higher-numbered locations:"
10190 #: ../source/book.xml:14299
10191 msgid "Command-line options"
10195 #: ../source/book.xml:14302
10196 msgid "The per-user INI files"
10200 #: ../source/book.xml:14305
10201 msgid "The per-user Registry values"
10205 #: ../source/book.xml:14308
10206 msgid "The system-wide INI files"
10210 #: ../source/book.xml:14311
10211 msgid "The system-wide Registry values"
10215 #: ../source/book.xml:14314
10216 msgid "Also, the Windows Registry doesn't really support the notion of something being <quote>commented out</quote>. However, Subversion will ignore any option key whose name begins with a hash (<literal>#</literal>) character. This allows you to effectively comment out a Subversion option without deleting the entire key from the Registry, obviously simplifying the process of restoring that option."
10220 #: ../source/book.xml:14321
10221 msgid "The <command>svn</command> command-line client never attempts to write to the Windows Registry, and will not attempt to create a default configuration area there. You can create the keys you need using the <command>REGEDIT</command> program. Alternatively, you can create a <filename>.reg</filename> file, and then double-click on that file from the Explorer shell, which will cause the data to be merged into your registry."
10225 #: ../source/book.xml:14331
10226 msgid "Sample Registration Entries (.reg) File."
10230 #: ../source/book.xml:14333
10232 msgid "\nREGEDIT4\n\n[HKEY_LOCAL_MACHINE\\Software\\Tigris.org\\Subversion\\Servers\\groups]\n\n[HKEY_LOCAL_MACHINE\\Software\\Tigris.org\\Subversion\\Servers\\global]\n\"#http-proxy-host\"=\"\"\n\"#http-proxy-port\"=\"\"\n\"#http-proxy-username\"=\"\"\n\"#http-proxy-password\"=\"\"\n\"#http-proxy-exceptions\"=\"\"\n\"#http-timeout\"=\"0\"\n\"#http-compression\"=\"yes\"\n\"#neon-debug-mask\"=\"\"\n\"#ssl-authority-files\"=\"\"\n\"#ssl-trust-default-ca\"=\"\"\n\"#ssl-client-cert-file\"=\"\"\n\"#ssl-client-cert-password\"=\"\"\n\n[HKEY_CURRENT_USER\\Software\\Tigris.org\\Subversion\\Config\\auth]\n\"#store-passwords\"=\"yes\"\n\"#store-auth-creds\"=\"yes\"\n\n[HKEY_CURRENT_USER\\Software\\Tigris.org\\Subversion\\Config\\helpers]\n\"#editor-cmd\"=\"notepad\"\n\"#diff-cmd\"=\"\"\n\"#diff3-cmd\"=\"\"\n\"#diff3-has-program-arg\"=\"\"\n\n[HKEY_CURRENT_USER\\Software\\Tigris.org\\Subversion\\Config\\tunnels]\n\n[HKEY_CURRENT_USER\\Software\\Tigris.org\\Subversion\\Config\\miscellany]\n\"#global-ignores\"=\"*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store\"\n\"#log-encoding\"=\"\"\n\"#use-commit-times\"=\"\"\n\"#no-unlock\"=\"\"\n\"#enable-auto-props\"=\"\"\n\n[HKEY_CURRENT_USER\\Software\\Tigris.org\\Subversion\\Config\\auto-props]\n\n"
10236 #: ../source/book.xml:14375
10237 msgid "The previous example shows the contents of a <filename>.reg</filename> file which contains some of the most commonly used configuration options and their default values. Note the presence of both system-wide (for network proxy-related options) and per-user settings (editor programs and password storage, among others). Also note that all the options are effectively commented out. You need only to remove the hash (<literal>#</literal>) character from the beginning of the option names, and set the values as you desire."
10241 #: ../source/book.xml:14389
10242 msgid "Configuration Options"
10245 #. TODO(cmpilato): Rework and move this section to the Reference
10247 #: ../source/book.xml:14392
10248 msgid "In this section, we will discuss the specific run-time configuration options that are currently supported by Subversion."
10252 #: ../source/book.xml:14398
10257 #: ../source/book.xml:14400
10258 msgid "The <filename>servers</filename> file contains Subversion configuration options related to the network layers. There are two special section names in this file—<literal>groups</literal> and <literal>global</literal>. The <literal>groups</literal> section is essentially a cross-reference table. The keys in this section are the names of other sections in the file; their values are <firstterm>globs</firstterm>—textual tokens which possibly contain wildcard characters—that are compared against the hostnames of the machine to which Subversion requests are sent."
10262 #: ../source/book.xml:14411
10264 msgid "\n[groups]\nbeanie-babies = *.red-bean.com\ncollabnet = svn.collab.net\n\n[beanie-babies]\n…\n\n[collabnet]\n…\n"
10268 #: ../source/book.xml:14422
10269 msgid "When Subversion is used over a network, it attempts to match the name of the server it is trying to reach with a group name under the <literal>groups</literal> section. If a match is made, Subversion then looks for a section in the <filename>servers</filename> file whose name is the matched group's name. From that section it reads the actual network configuration settings."
10273 #: ../source/book.xml:14429
10274 msgid "The <literal>global</literal> section contains the settings that are meant for all of the servers not matched by one of the globs under the <literal>groups</literal> section. The options available in this section are exactly the same as those valid for the other server sections in the file (except, of course, the special <literal>groups</literal> section), and are as follows:"
10278 #: ../source/book.xml:14440
10279 msgid "http-proxy-exceptions"
10283 #: ../source/book.xml:14443
10284 msgid "This specifies a comma-separated list of patterns for repository hostnames that should accessed directly, without using the proxy machine. The pattern syntax is the same as is used in the Unix shell for filenames. A repository hostname matching any of these patterns will not be proxied."
10288 #: ../source/book.xml:14453
10289 msgid "http-proxy-host"
10293 #: ../source/book.xml:14456
10294 msgid "This specifies the hostname of the proxy computer through which your HTTP-based Subversion requests must pass. It defaults to an empty value, which means that Subversion will not attempt to route HTTP requests through a proxy computer, and will instead attempt to contact the destination machine directly."
10298 #: ../source/book.xml:14466
10299 msgid "http-proxy-port"
10303 #: ../source/book.xml:14469
10304 msgid "This specifies the port number on the proxy host to use. It defaults to an empty value."
10308 #: ../source/book.xml:14475
10309 msgid "http-proxy-username"
10313 #: ../source/book.xml:14478
10314 msgid "This specifies the username to supply to the proxy machine. It defaults to an empty value."
10318 #: ../source/book.xml:14484
10319 msgid "http-proxy-password"
10323 #: ../source/book.xml:14487
10324 msgid "This specifies the password to supply to the proxy machine. It defaults to an empty value."
10328 #: ../source/book.xml:14493
10329 msgid "http-timeout"
10333 #: ../source/book.xml:14496
10334 msgid "This specifies the amount of time, in seconds, to wait for a server response. If you experience problems with a slow network connection causing Subversion operations to time out, you should increase the value of this option. The default value is <literal>0</literal>, which instructs the underlying HTTP library, Neon, to use its default timeout setting."
10338 #: ../source/book.xml:14508
10339 msgid "http-compression"
10343 #: ../source/book.xml:14511
10344 msgid "This specifies whether or not Subversion should attempt to compress network requests made to DAV-ready servers. The default value is <literal>yes</literal> (though compression will only occur if that capability is compiled into the network layer). Set this to <literal>no</literal> to disable compression, such as when debugging network transmissions."
10348 #: ../source/book.xml:14522
10349 msgid "neon-debug-mask"
10353 #: ../source/book.xml:14525
10354 msgid "This is an integer mask that the underlying HTTP library, Neon, uses for choosing what type of debugging output to yield. The default value is <literal>0</literal>, which will silence all debugging output. For more information about how Subversion makes use of Neon, see <xref linkend=\"svn.developer\"/>."
10358 #: ../source/book.xml:14535
10359 msgid "ssl-authority-files"
10363 #: ../source/book.xml:14538
10364 msgid "This is a semicolon-delimited list of paths to files containing certificates of the certificate authorities (or CAs) that are accepted by the Subversion client when accessing the repository over HTTPS."
10368 #: ../source/book.xml:14547
10369 msgid "ssl-trust-default-ca"
10373 #: ../source/book.xml:14550
10374 msgid "Set this variable to <literal>yes</literal> if you want Subversion to automatically trust the set of default CAs that ship with OpenSSL."
10378 #: ../source/book.xml:14557
10379 msgid "ssl-client-cert-file"
10383 #: ../source/book.xml:14560
10384 msgid "If a host (or set of hosts) requires an SSL client certificate, you'll normally be prompted for a path to your certificate. By setting this variable to that same path, Subversion will be able to find your client certificate automatically without prompting you. There's no standard place to store your certificate on disk; Subversion will grab it from any path you specify."
10388 #: ../source/book.xml:14572
10389 msgid "ssl-client-cert-password"
10393 #: ../source/book.xml:14575
10394 msgid "If your SSL client certificate file is encrypted by a passphrase, Subversion will prompt you for the passphrase whenever the certificate is used. If you find this annoying (and don't mind storing the password in the <filename>servers</filename> file), then you can set this variable to the certificate's passphrase. You won't be prompted anymore."
10398 #: ../source/book.xml:14589
10403 #: ../source/book.xml:14591
10404 msgid "The <filename>config</filename> file contains the rest of the currently available Subversion run-time options, those not related to networking. There are only a few options in use as of this writing, but they are again grouped into sections in expectation of future additions."
10408 #: ../source/book.xml:14596
10409 msgid "The <literal>auth</literal> section contains settings related to Subversion's authentication and authorization against the repository. It contains:"
10413 #: ../source/book.xml:14602
10414 msgid "store-passwords"
10418 #: ../source/book.xml:14605
10419 msgid "This instructs Subversion to cache, or not to cache, passwords that are supplied by the user in response to server authentication challenges. The default value is <literal>yes</literal>. Set this to <literal>no</literal> to disable this on-disk password caching. You can override this option for a single instance of the <command>svn</command> command using the <option>--no-auth-cache</option> command-line parameter (for those subcommands that support it). For more information, see <xref linkend=\"svn.serverconfig.netmodel.credcache\"/>."
10423 #: ../source/book.xml:14619
10424 msgid "store-auth-creds"
10428 #: ../source/book.xml:14622
10429 msgid "This setting is the same as <literal>store-passwords</literal>, except that it enables or disables disk-caching of <emphasis>all</emphasis> authentication information: usernames, passwords, server certificates, and any other types of cacheable credentials."
10433 #: ../source/book.xml:14631
10434 msgid "The <literal>helpers</literal> section controls which external applications Subversion uses to accomplish its tasks. Valid options in this section are:"
10438 #: ../source/book.xml:14637
10443 #: ../source/book.xml:14640
10444 msgid "This specifies the program Subversion will use to query the user for a log message during a commit operation, such as when using <command>svn commit</command> without either the <option>--message</option> (<option>-m</option>) or <option>--file</option> (<option>-F</option>) options. This program is also used with the <command>svn propedit</command> command—a temporary file is populated with the current value of the property the user wishes to edit, and the edits take place right in the editor program (see <xref linkend=\"svn.advanced.props\"/>). This option's default value is empty. The order of priority for determining the editor command (where lower-numbered locations take precedence over higher-numbered locations) is:"
10448 #: ../source/book.xml:14656
10449 msgid "Command-line option <literal>--editor-cmd</literal>"
10453 #: ../source/book.xml:14659
10454 msgid "Environment variable <literal>SVN_EDITOR</literal>"
10458 #: ../source/book.xml:14662
10459 msgid "Configuration option <literal>editor-cmd</literal>"
10463 #: ../source/book.xml:14665
10464 msgid "Environment variable <literal>VISUAL</literal>"
10468 #: ../source/book.xml:14668
10469 msgid "Environment variable <literal>EDITOR</literal>"
10473 #: ../source/book.xml:14671
10474 msgid "Possibly, a default value built in to Subversion (not present in the official builds)"
10478 #: ../source/book.xml:14675
10479 msgid "The value of any of these options or variables is (unlike <literal>diff-cmd</literal>) the beginning of a command line to be executed by the shell. Subversion appends a space and the pathname of the temporary file to be edited. The editor should modify the temporary file and return a zero exit code to indicate success."
10483 #: ../source/book.xml:14685
10488 #: ../source/book.xml:14688
10489 msgid "This specifies the absolute path of a differencing program, used when Subversion generates <quote>diff</quote> output (such as when using the <command>svn diff</command> command). By default Subversion uses an internal differencing library—setting this option will cause it to perform this task using an external program. See <xref linkend=\"svn.advanced.externaldifftools\"/> for more details on using such programs."
10493 #: ../source/book.xml:14701
10498 #: ../source/book.xml:14704
10499 msgid "This specifies the absolute path of a three-way differencing program. Subversion uses this program to merge changes made by the user with those received from the repository. By default Subversion uses an internal differencing library—setting this option will cause it to perform this task using an external program. See <xref linkend=\"svn.advanced.externaldifftools\"/> for more details on using such programs."
10503 #: ../source/book.xml:14716
10504 msgid "diff3-has-program-arg"
10508 #: ../source/book.xml:14719
10509 msgid "This flag should be set to <literal>true</literal> if the program specified by the <literal>diff3-cmd</literal> option accepts a <option>--diff-program</option> command-line parameter."
10513 #: ../source/book.xml:14727
10514 msgid "The <literal>tunnels</literal> section allows you to define new tunnel schemes for use with <command>svnserve</command> and <literal>svn://</literal> client connections. For more details, see <xref linkend=\"svn.serverconfig.svnserve.sshauth\"/>."
10518 #: ../source/book.xml:14733
10519 msgid "Anyone for potluck dinner?"
10523 #: ../source/book.xml:14731
10524 msgid "The <literal>miscellany</literal> section is where everything that doesn't belong elsewhere winds up. <placeholder-1/> In this section, you can find:"
10528 #: ../source/book.xml:14738
10529 msgid "global-ignores"
10533 #: ../source/book.xml:14741
10534 msgid "When running the <command>svn status</command> command, Subversion lists unversioned files and directories along with the versioned ones, annotating them with a <literal>?</literal> character (see <xref linkend=\"svn.tour.cycle.examine.status\"/>). Sometimes, it can be annoying to see uninteresting, unversioned items—for example, object files that result from a program's compilation—in this display. The <literal>global-ignores</literal> option is a list of whitespace-delimited globs which describe the names of files and directories that Subversion should not display unless they are versioned. The default value is <literal>*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store</literal>."
10538 #: ../source/book.xml:14754
10539 msgid "As well as <command>svn status</command>, the <command>svn add</command> and <command>svn import</command> commands also ignore files that match the list when they are scanning a directory. You can override this behaviour for a single instance of any of these commands by explicitly specifying the file name, or by using the <option>--no-ignore</option> command-line flag."
10543 #: ../source/book.xml:14761
10544 msgid "For information on more fine-grained control of ignored items, see <xref linkend=\"svn.advanced.props.special.ignore\"/>."
10548 #: ../source/book.xml:14767
10549 msgid "enable-auto-props"
10553 #: ../source/book.xml:14770
10554 msgid "This instructs Subversion to automatically set properties on newly added or imported files. The default value is <literal>no</literal>, so set this to <literal>yes</literal> to enable Auto-props. The <literal>auto-props</literal> section of this file specifies which properties are to be set on which files."
10558 #: ../source/book.xml:14780
10559 msgid "log-encoding"
10563 #: ../source/book.xml:14783
10564 msgid "This variable sets the default character set encoding for commit log messages. It's a permanent form of the <option>--encoding</option> option (see <xref linkend=\"svn.ref.svn.sw\"/>). The Subversion repository stores log messages in UTF-8, and assumes that your log message is written using your operating system's native locale. You should specify a different encoding if your commit messages are written in any other encoding."
10568 #: ../source/book.xml:14796
10569 msgid "use-commit-times"
10573 #: ../source/book.xml:14799
10574 msgid "Normally your working copy files have timestamps that reflect the last time they were touched by any process, whether that be your own editor or by some <command>svn</command> subcommand. This is generally convenient for people developing software, because build systems often look at timestamps as a way of deciding which files need to be recompiled."
10578 #: ../source/book.xml:14806
10579 msgid "In other situations, however, it's sometimes nice for the working copy files to have timestamps that reflect the last time they were changed in the repository. The <command>svn export</command> command always places these <quote>last-commit timestamps</quote> on trees that it produces. By setting this config variable to <literal>yes</literal>, the <command>svn checkout</command>, <command>svn update</command>, <command>svn switch</command>, and <command>svn revert</command> commands will also set last-commit timestamps on files that they touch."
10583 #: ../source/book.xml:14823
10584 msgid "The <literal>auto-props</literal> section controls the Subversion client's ability to automatically set properties on files when they are added or imported. It contains any number of key-value pairs in the format <literal>PATTERN = PROPNAME=PROPVALUE</literal> where <literal>PATTERN</literal> is a file pattern that matches a set of filenames and the rest of the line is the property and its value. Multiple matches on a file will result in multiple propsets for that file; however, there is no guarantee that auto-props will be applied in the order in which they are listed in the config file, so you can't have one rule <quote>override</quote> another. You can find several examples of auto-props usage in the <filename>config</filename> file. Lastly, don't forget to set <literal>enable-auto-props</literal> to <literal>yes</literal> in the <literal>miscellany</literal> section if you want to enable auto-props."
10588 #: ../source/book.xml:14849
10589 msgid "Localization"
10593 #: ../source/book.xml:14851
10594 msgid "<firstterm>Localization</firstterm> is the act of making programs behave in a region-specific way. When a program formats numbers or dates in a way specific to your part of the world, or prints messages (or accepts input) in your native language, the program is said to be <firstterm>localized</firstterm>. This section describes steps Subversion has made towards localization."
10598 #: ../source/book.xml:14861
10599 msgid "Understanding locales"
10603 #: ../source/book.xml:14863
10604 msgid "Most modern operating systems have a notion of the <quote>current locale</quote>—that is, the region or country whose localization conventions are honored. These conventions—typically chosen by some runtime configuration mechanism on the computer—affect the way in which programs present data to the user, as well as the way in which they accept user input."
10608 #: ../source/book.xml:14870
10609 msgid "On most Unix-like systems, you can check the values of the locale-related runtime configuration options by running the <command>locale</command> command:"
10613 #: ../source/book.xml:14873
10615 msgid "\n$ locale\nLANG=\nLC_COLLATE=\"C\"\nLC_CTYPE=\"C\"\nLC_MESSAGES=\"C\"\nLC_MONETARY=\"C\"\nLC_NUMERIC=\"C\"\nLC_TIME=\"C\"\nLC_ALL=\"C\"\n"
10619 #: ../source/book.xml:14884
10620 msgid "The output is a list of locale-related environment variables and their current values. In this example, the variables are all set to the default <literal>C</literal> locale, but users can set these variables to specific country/language code combinations. For example, if one were to set the <literal>LC_TIME</literal> variable to <literal>fr_CA</literal>, then programs would know to present time and date information formatted according a French-speaking Canadian's expectations. And if one were to set the <literal>LC_MESSAGES</literal> variable to <literal>zh_TW</literal>, then programs would know to present human-readable messages in Traditional Chinese. Setting the <literal>LC_ALL</literal> variable has the effect of changing every locale variable to the same value. The value of <literal>LANG</literal> is used as a default value for any locale variable that is unset. To see the list of available locales on a Unix system, run the command <command>locale -a</command>."
10624 #: ../source/book.xml:14902
10625 msgid "On Windows, locale configuration is done via the <quote>Regional and Language Options</quote> control panel item. There you can view and select the values of individual settings from the available locales, and even customize (at a sickening level of detail) several of the display formatting conventions."
10629 #: ../source/book.xml:14912
10630 msgid "Subversion's use of locales"
10634 #: ../source/book.xml:14914
10635 msgid "The Subversion client, <command>svn</command>, honors the current locale configuration in two ways. First, it notices the value of the <literal>LC_MESSAGES</literal> variable and attempts to print all messages in the specified language. For example:"
10639 #: ../source/book.xml:14919
10641 msgid "\n$ export LC_MESSAGES=de_DE\n$ svn help cat\ncat: Gibt den Inhalt der angegebenen Dateien oder URLs aus.\nAufruf: cat ZIEL[@REV]...\n…\n"
10645 #: ../source/book.xml:14926
10646 msgid "This behavior works identically on both Unix and Windows systems. Note, though, that while your operating system might have support for a certain locale, the Subversion client still may not be able to speak the particular language. In order to produce localized messages, human volunteers must provide translations for each language. The translations are written using the GNU gettext package, which results in translation modules that end with the <filename>.mo</filename> filename extension. For example, the German translation file is named <filename>de.mo</filename>. These translation files are installed somewhere on your system. On Unix, they typically live in <filename>/usr/share/locale/</filename>, while on Windows they're often found in the <filename>\\share\\locale\\</filename> folder in Subversion's installation area. Once installed, a module is named after the program it provides translations for. For example, the <filename>de.mo</filename> file may ultimately end up installed as <filename>/usr/share/locale/de/LC_MESSAGES/subversion.mo</filename>. By browsing the installed <filename>.mo</filename> files, you can see which languages the Subversion client is able to speak."
10650 #: ../source/book.xml:14948
10651 msgid "The second way in which the locale is honored involves how <command>svn</command> interprets your input. The repository stores all paths, filenames, and log messages in Unicode, encoded as UTF-8. In that sense, the repository is <firstterm>internationalized</firstterm>—that is, the repository is ready to accept input in any human language. This means, however, that the Subversion client is responsible for sending only UTF-8 filenames and log messages into the repository. In order to do this, it must convert the data from the native locale into UTF-8."
10655 #: ../source/book.xml:14958
10656 msgid "For example, suppose you create a file named <filename>caffè.txt</filename>, and then when committing the file, you write the log message as <quote>Adesso il caffè è più forte</quote>. Both the filename and log message contain non-ASCII characters, but because your locale is set to <literal>it_IT</literal>, the Subversion client knows to interpret them as Italian. It uses an Italian character set to convert the data to UTF-8 before sending them off to the repository."
10660 #: ../source/book.xml:14967
10661 msgid "Note that while the repository demands UTF-8 filenames and log messages, it <emphasis>does not</emphasis> pay attention to file contents. Subversion treats file contents as opaque strings of bytes, and neither client nor server makes an attempt to understand the character set or encoding of the contents."
10665 #: ../source/book.xml:14975
10666 msgid "Character set conversion errors"
10670 #: ../source/book.xml:14977
10671 msgid "While using Subversion, you might get hit with an error related to character set conversions:"
10675 #: ../source/book.xml:14979
10677 msgid "\nsvn: Can't convert string from native encoding to 'UTF-8':\n…\nsvn: Can't convert string from 'UTF-8' to native encoding:\n…\n"
10681 #: ../source/book.xml:14985
10682 msgid "Errors like this typically occur when the Subversion client has received a UTF-8 string from the repository, but not all of the characters in that string can be represented using the encoding of the current locale. For example, if your locale is <literal>en_US</literal> but a collaborator has committed a Japanese filename, you're likely to see this error when you receive the file during an <command>svn update</command>."
10686 #: ../source/book.xml:14993
10687 msgid "The solution is either to set your locale to something which <emphasis>can</emphasis> represent the incoming UTF-8 data, or to change the filename or log message in the repository. (And don't forget to slap your collaborator's hand—projects should decide on common languages ahead of time, so that all participants are using the same locale.)"
10691 #: ../source/book.xml:15008
10692 msgid "Using External Differencing Tools"
10696 #: ../source/book.xml:15010
10697 msgid "The presence of <option>--diff-cmd</option> and <option>--diff3-cmd</option> options, and similarly named runtime configuration parameters (see <xref linkend=\"svn.advanced.confarea.opts.config\"/>), can lead to a false notion of how easy it is to use external differencing (or <quote>diff</quote>) and merge tools with Subversion. While Subversion can use most of popular such tools available, the effort invested in setting this up often turns out to be non-trivial."
10701 #: ../source/book.xml:15028
10702 msgid "Subversion developers are good, but even the best make mistakes."
10706 #: ../source/book.xml:15018
10707 msgid "The interface between Subversion and external diff and merge tools harkens back to a time when Subversion's only contextual differencing capabilities were built around invocations of the GNU diffutils toolchain, specifically the <command>diff</command> and <command>diff3</command> utilities. To get the kind of behavior Subversion needed, it called these utilities with more than a handful of options and parameters, most of which were quite specific to the utilities. Some time later, Subversion grew its own internal differencing library, and as a failover mechanism, <placeholder-1/> the <option>--diff-cmd</option> and <option>--diff3-cmd</option> options were added to the Subversion command-line client so users could more easily indicate that they preferred to use the GNU diff and diff3 utilities instead of the newfangled internal diff library. If those options were used, Subversion would simply ignore the internal diff library, and fall back to running those external programs, lengthy argument lists and all. And that's where things remain today."
10711 #: ../source/book.xml:15038
10712 msgid "It didn't take long for folks to realize that having such easy configuration mechanisms for specifying that Subversion should use the external GNU diff and diff3 utilities located at a particular place on the system could be applied toward the use of other diff and merge tools, too. After all, Subversion didn't actually verify that the things it was being told to run were members of the GNU diffutils toolchain. But the only configurable aspect of using those external tools is their location on the system—not the option set, parameter order, etc. Subversion continues throwing all those GNU utility options at your external diff tool regardless of whether or not that program can understand those options. And that's where things get unintuitive for most users."
10716 #: ../source/book.xml:15051
10717 msgid "The key to using external diff and merge tools (other than GNU diff and diff3, of course) with Subversion is to use wrapper scripts which convert the input from Subversion into something that your differencing tool can understand, and then to convert the output of your tool back into a format which Subversion expects—the format that the GNU tools would have used. The following sections cover the specifics of those expectations."
10721 #: ../source/book.xml:15060
10722 msgid "The decision on when to fire off a contextual diff or merge as part of a larger Subversion operation is made entirely by Subversion, and is affected by, among other things, whether or not the files being operated on are human-readable as determined by their <literal>svn:mime-type</literal> property. This means, for example, that even if you had the niftiest Microsoft Word-aware differencing or merging tool in the Universe, it would never be invoked by Subversion so long as your versioned Word documents had a configured MIME type that denoted that they were not human-readable (such as <literal>application/msword</literal>). For more about MIME type settings, see <xref linkend=\"svn.advanced.props.special.mime-type\"/>"
10726 #: ../source/book.xml:15077
10727 msgid "External diff"
10731 #: ../source/book.xml:15093
10732 msgid "The GNU diff manual page puts it this way: <quote>An exit status of 0 means no differences were found, 1 means some differences were found, and 2 means trouble.</quote>"
10736 #: ../source/book.xml:15079
10737 msgid "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 programs, 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 <quote>backgrounded</quote>), you might have several instances of it all running simultaneously. Finally, Subversion expects that your program return an error code of 1 if your program detected differences, or 0 if it did not—any other error code is considered a fatal error. <placeholder-1/>"
10741 #: ../source/book.xml:15097
10742 msgid "<xref linkend=\"svn.advanced.externaldifftools.diff.ex-1\"/> and <xref linkend=\"svn.advanced.externaldifftools.diff.ex-2\"/> are templates for external diff tool wrappers in the Bourne shell and Windows batch scripting languages, respectively."
10746 #: ../source/book.xml:15104
10747 msgid "diffwrap.sh"
10751 #: ../source/book.xml:15106
10753 msgid "\n#!/bin/sh\n\n# Configure your favorite diff program here.\nDIFF=\"/usr/local/bin/my-diff-tool\"\n\n# Subversion provides the paths we need as the sixth and seventh \n# parameters.\nLEFT=${6}\nRIGHT=${7}\n\n# Call the diff command (change the following line to make sense for\n# your merge program).\n$DIFF --left $LEFT --right $RIGHT\n\n# Return an errorcode of 0 if no differences were detected, 1 if some were.\n# Any other errorcode will be treated as fatal.\n"
10757 #: ../source/book.xml:15127
10758 msgid "diffwrap.bat"
10762 #: ../source/book.xml:15129
10764 msgid "\n@ECHO OFF\n\nREM Configure your favorite diff program here.\nSET DIFF=\"C:\\Program Files\\Funky Stuff\\My Diff Tool.exe\"\n\nREM Subversion provides the paths we need as the sixth and seventh \nREM parameters.\nSET LEFT=%6\nSET RIGHT=%7\n\nREM Call the diff command (change the following line to make sense for\nREM your merge program).\n%DIFF% --left %LEFT% --right %RIGHT%\n\nREM Return an errorcode of 0 if no differences were detected, 1 if some were.\nREM Any other errorcode will be treated as fatal.\n"
10768 #: ../source/book.xml:15152
10769 msgid "External diff3"
10773 #: ../source/book.xml:15154
10774 msgid "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 <quote>mine</quote>, <quote>older</quote>, and <quote>yours</quote> 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 error code of 0 if the merge was successful, or 1 if unresolved conflicts remain in the output—any other error code is considered a fatal error."
10778 #: ../source/book.xml:15171
10779 msgid "<xref linkend=\"svn.advanced.externaldifftools.diff3.ex-1\"/> and <xref linkend=\"svn.advanced.externaldifftools.diff3.ex-2\"/> are templates for external merge tool wrappers in the Bourne shell and Windows batch scripting languages, respectively."
10783 #: ../source/book.xml:15177
10784 msgid "diff3wrap.sh"
10788 #: ../source/book.xml:15179
10790 msgid "\n#!/bin/sh\n\n# Configure your favorite diff3/merge program here.\nDIFF3=\"/usr/local/bin/my-merge-tool\"\n\n# Subversion provides the paths we need as the ninth, tenth, and eleventh \n# parameters.\nMINE=${9}\nOLDER=${10}\nYOURS=${11}\n\n# Call the merge command (change the following line to make sense for\n# your merge program).\n$DIFF3 --older $OLDER --mine $MINE --yours $YOURS\n\n# After performing the merge, this script needs to print the contents\n# of the merged file to stdout. Do that in whatever way you see fit.\n# Return an errorcode of 0 on successful merge, 1 if unresolved conflicts\n# remain in the result. Any other errorcode will be treated as fatal.\n"
10794 #: ../source/book.xml:15203
10795 msgid "diff3wrap.bat"
10799 #: ../source/book.xml:15205
10801 msgid "\n@ECHO OFF\n\nREM Configure your favorite diff3/merge program here.\nSET DIFF3=\"C:\\Program Files\\Funky Stuff\\My Merge Tool.exe\"\n\nREM Subversion provides the paths we need as the ninth, tenth, and eleventh \nREM parameters. But we only have access to nine parameters at a time, so we\nREM shift our nine-parameter window twice to let us get to what we need.\nSHIFT\nSHIFT\nSET MINE=%7\nSET OLDER=%8\nSET YOURS=%9\n\nREM Call the merge command (change the following line to make sense for\nREM your merge program).\n%DIFF3% --older %OLDER% --mine %MINE% --yours %YOURS%\n\nREM After performing the merge, this script needs to print the contents\nREM of the merged file to stdout. Do that in whatever way you see fit.\nREM Return an errorcode of 0 on successful merge, 1 if unresolved conflicts\nREM remain in the result. Any other errorcode will be treated as fatal.\n"
10805 #: ../source/book.xml:15240
10806 msgid "Embedding Subversion"
10810 #: ../source/book.xml:15242
10811 msgid "Subversion has a modular design: it's implemented as a collection of libraries written in C. Each library has a well-defined purpose and Application Programming Interface (API), and that interface is available not only for Subversion itself to use, but for any software that wishes to embed or otherwise programmatically control Subversion. Additionally, Subversion's API is available not only to other C programs, but also to programs written in higher-level languages such as Python, Perl, Java, or Ruby."
10815 #: ../source/book.xml:15251
10816 msgid "This chapter is for those who wish to interact with Subversion through its public API or its various language bindings. If you wish to write robust wrapper scripts around Subversion functionality to simplify your own life, are trying to develop more complex integrations between Subversion and other pieces of software, or just have an interest in Subversion's various library modules and what they offer, this chapter is for you. If, however, you don't foresee yourself participating with Subversion at such a level, feel free to skip this chapter with the confidence that your experience as a Subversion user will not be affected."
10820 #: ../source/book.xml:15267
10821 msgid "Layered Library Design"
10825 #: ../source/book.xml:15269
10826 msgid "Each of Subversion's core libraries can be said to exist in one of three main layers—the Repository Layer, the Repository Access (RA) Layer, or the Client Layer (see <xref linkend=\"svn.intro.architecture.dia-1\"/>). We will examine these layers shortly, but first, let's briefly summarize Subversion's various libraries. For the sake of consistency, we will refer to the libraries by their extensionless Unix library names (libsvn_fs, libsvn_wc, mod_dav_svn, etc.)."
10830 #: ../source/book.xml:15278
10831 msgid "libsvn_client"
10835 #: ../source/book.xml:15280
10836 msgid "Primary interface for client programs"
10840 #: ../source/book.xml:15285
10841 msgid "libsvn_delta"
10845 #: ../source/book.xml:15287
10846 msgid "Tree and byte-stream differencing routines"
10850 #: ../source/book.xml:15292
10851 msgid "libsvn_diff"
10855 #: ../source/book.xml:15294
10856 msgid "Contextual differencing and merging routines"
10860 #: ../source/book.xml:15299
10865 #: ../source/book.xml:15301
10866 msgid "Filesystem commons and module loader"
10870 #: ../source/book.xml:15306
10871 msgid "libsvn_fs_base"
10875 #: ../source/book.xml:15308
10876 msgid "The Berkeley DB filesystem back-end"
10880 #: ../source/book.xml:15313
10881 msgid "libsvn_fs_fs"
10885 #: ../source/book.xml:15315
10886 msgid "The native filesystem (FSFS) back-end"
10890 #: ../source/book.xml:15320
10895 #: ../source/book.xml:15322
10896 msgid "Repository Access commons and module loader"
10900 #: ../source/book.xml:15327
10901 msgid "libsvn_ra_dav"
10905 #: ../source/book.xml:15329
10906 msgid "The WebDAV Repository Access module"
10910 #: ../source/book.xml:15334
10911 msgid "libsvn_ra_local"
10915 #: ../source/book.xml:15336
10916 msgid "The local Repository Access module"
10920 #: ../source/book.xml:15341
10921 msgid "libsvn_ra_serf"
10925 #: ../source/book.xml:15343
10926 msgid "Another (experimental) WebDAV Repository Access module"
10930 #: ../source/book.xml:15348
10931 msgid "libsvn_ra_svn"
10935 #: ../source/book.xml:15350
10936 msgid "The custom protocol Repository Access module"
10940 #: ../source/book.xml:15355
10941 msgid "libsvn_repos"
10945 #: ../source/book.xml:15357
10946 msgid "Repository interface"
10950 #: ../source/book.xml:15361
10951 msgid "libsvn_subr"
10955 #: ../source/book.xml:15363
10956 msgid "Miscellaneous helpful subroutines"
10960 #: ../source/book.xml:15368
10965 #: ../source/book.xml:15370
10966 msgid "The working copy management library"
10970 #: ../source/book.xml:15375
10971 msgid "mod_authz_svn"
10975 #: ../source/book.xml:15377
10976 msgid "Apache authorization module for Subversion repositories access via WebDAV"
10980 #: ../source/book.xml:15384
10981 msgid "Apache module for mapping WebDAV operations to Subversion ones"
10985 #: ../source/book.xml:15389
10986 msgid "The fact that the word <quote>miscellaneous</quote> only appears once in the previous list is a good sign. The Subversion development team is serious about making sure that functionality lives in the right layer and libraries. Perhaps the greatest advantage of the modular design is its lack of complexity from a developer's point of view. As a developer, you can quickly formulate that kind of <quote>big picture</quote> that allows you to pinpoint the location of certain pieces of functionality with relative ease."
10990 #: ../source/book.xml:15398
10991 msgid "Another benefit of modularity is the ability to replace a given module with a whole new library that implements the same API without affecting the rest of the code base. In some sense, this happens within Subversion already. The libsvn_ra_dav, libsvn_ra_local, libsvn_ra_serf, and libsvn_ra_svn libraries each implement the same interface, all working as plugins to libsvn_ra. And all four communicate with the Repository Layer—libsvn_ra_local connects to the repository directly; the other three do so over a network. The libsvn_fs_base and libsvn_fs_fs libraries are another pair of libraries that implement the same functionality in different ways—both are plugins to the common libsvn_fs library."
10995 #: ../source/book.xml:15410
10996 msgid "The client itself also highlights the benefits of modularity in the Subversion design. Subversion's libsvn_client library is a one-stop shop for most of the functionality necessary for designing a working Subversion client (see <xref linkend=\"svn.developer.layerlib.client\"/>). So while the Subversion distribution provides only the <command>svn</command> command-line client program, there are several third-party programs which provide various forms of graphical client UI. These GUIs use the same APIs that the stock command-line client does. This type of modularity has played a large role in the proliferation of available Subversion clients and IDE integrations and, by extension, to the tremendous adoption rate of Subversion itself."
11000 #: ../source/book.xml:15425
11001 msgid "Repository Layer"
11005 #: ../source/book.xml:15427
11006 msgid "When referring to Subversion's Repository Layer, we're generally talking about two basic concepts—the versioned filesystem implementation (accessed via libsvn_fs, and supported by its libsvn_fs_base and libsvn_fs_fs plugins), and the repository logic that wraps it (as implemented in libsvn_repos). These libraries provide the storage and reporting mechanisms for the various revisions of your version-controlled data. This layer is connected to the Client Layer via the Repository Access Layer, and is, from the perspective of the Subversion user, the stuff at the <quote>other end of the line.</quote>"
11010 #: ../source/book.xml:15438
11011 msgid "The Subversion Filesystem is not a kernel-level filesystem that one would install in an operating system (like the Linux ext2 or NTFS), but a virtual filesystem. Rather than storing <quote>files</quote> and <quote>directories</quote> as real files and directories (as in, the kind you can navigate through using your favorite shell program), it uses one of two available abstract storage backends—either a Berkeley DB database environment, or a flat-file representation. (To learn more about the two repository back-ends, see <xref linkend=\"svn.reposadmin.basics.backends\"/>.) There has even been considerable interest by the development community in giving future releases of Subversion the ability to use other back-end database systems, perhaps through a mechanism such as Open Database Connectivity (ODBC). In fact, Google did something similar to this before launching the Google Code Project Hosting service: they announced in mid-2006 that members of its Open Source team had written a new proprietary Subversion filesystem plugin which used their ultra-scalable Bigtable database for its storage."
11015 #: ../source/book.xml:15456
11016 msgid "The filesystem API exported by libsvn_fs contains the kinds of functionality you would expect from any other filesystem API—you can create and remove files and directories, copy and move them around, modify file contents, and so on. It also has features that are not quite as common, such as the ability to add, modify, and remove metadata (<quote>properties</quote>) on each file or directory. Furthermore, the Subversion Filesystem is a versioning filesystem, which means that as you make changes to your directory tree, Subversion remembers what your tree looked like before those changes. And before the previous changes. And the previous ones. And so on, all the way back through versioning time to (and just beyond) the moment you first started adding things to the filesystem."
11020 #: ../source/book.xml:15470
11021 msgid "All the modifications you make to your tree are done within the context of a Subversion commit transaction. The following is a simplified general routine for modifying your filesystem:"
11025 #: ../source/book.xml:15476
11026 msgid "Begin a Subversion commit transaction."
11030 #: ../source/book.xml:15479
11031 msgid "Make your changes (adds, deletes, property modifications, etc.)."
11035 #: ../source/book.xml:15483
11036 msgid "Commit your transaction."
11040 #: ../source/book.xml:15486
11041 msgid "Once you have committed your transaction, your filesystem modifications are permanently stored as historical artifacts. Each of these cycles generates a single new revision of your tree, and each revision is forever accessible as an immutable snapshot of <quote>the way things were.</quote>"
11045 #: ../source/book.xml:15493
11046 msgid "The Transaction Distraction"
11050 #: ../source/book.xml:15495
11051 msgid "The notion of a Subversion transaction can become easily confused with the transaction support provided by the underlying database itself, especially given the former's close proximity to the Berkeley DB database code in libsvn_fs_base. Both types of transaction exist to provide atomicity and isolation. In other words, transactions give you the ability to perform a set of actions in an all-or-nothing fashion—either all the actions in the set complete with success, or they all get treated as if <emphasis>none</emphasis> of them ever happened—and in a way that does not interfere with other processes acting on the data."
11055 #: ../source/book.xml:15507
11056 msgid "Database transactions generally encompass small operations related specifically to the modification of data in the database itself (such as changing the contents of a table row). Subversion transactions are larger in scope, encompassing higher-level operations like making modifications to a set of files and directories which are intended to be stored as the next revision of the filesystem tree. If that isn't confusing enough, consider the fact that Subversion uses a database transaction during the creation of a Subversion transaction (so that if the creation of Subversion transaction fails, the database will look as if we had never attempted that creation in the first place)!"
11060 #: ../source/book.xml:15520
11061 msgid "Fortunately for users of the filesystem API, the transaction support provided by the database system itself is hidden almost entirely from view (as should be expected from a properly modularized library scheme). It is only when you start digging into the implementation of the filesystem itself that such things become visible (or interesting)."
11065 #: ../source/book.xml:15528
11066 msgid "Most of the functionality provided by the filesystem interface deals with actions that occur on individual filesystem paths. That is, from outside of the filesystem, the primary mechanism for describing and accessing the individual revisions of files and directories comes through the use of path strings like <filename>/foo/bar</filename>, just as if you were addressing files and directories through your favorite shell program. You add new files and directories by passing their paths-to-be to the right API functions. You query for information about them by the same mechanism."
11070 #: ../source/book.xml:15538
11071 msgid "Unlike most filesystems, though, a path alone is not enough information to identify a file or directory in Subversion. Think of a directory tree as a two-dimensional system, where a node's siblings represent a sort of left-and-right motion, and descending into subdirectories a downward motion. <xref linkend=\"svn.developer.layerlib.repos.dia-1\"/> shows a typical representation of a tree as exactly that."
11075 #: ../source/book.xml:15547
11076 msgid "Files and directories in two dimensions"
11080 #: ../source/book.xml:15558
11081 msgid "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 <emphasis>fourth</emphasis> dimension, and we apologize for any emotional trauma induced by our assertion of a different theory."
11085 #: ../source/book.xml:15555
11086 msgid "The difference here is that the Subversion filesystem has a nifty third dimension that most filesystems do not have—Time! <placeholder-1/> In the filesystem interface, nearly every function that has a <parameter>path</parameter> argument also expects a <parameter>root</parameter> argument. This svn_fs_root_t argument describes either a revision or a Subversion transaction (which is simply a revision-in-the-making), and provides that third-dimensional context needed to understand the difference between <filename>/foo/bar</filename> in revision 32, and the same path as it exists in revision 98. <xref linkend=\"svn.developer.layerlib.repos.dia-2\"/> shows revision history as an added dimension to the Subversion filesystem universe."
11090 #: ../source/book.xml:15576
11091 msgid "Versioning time—the third dimension!"
11095 #: ../source/book.xml:15584
11096 msgid "As we mentioned earlier, the libsvn_fs API looks and feels like any other filesystem, except that it has this wonderful versioning capability. It was designed to be usable by any program interested in a versioning filesystem. Not coincidentally, Subversion itself is interested in that functionality. But while the filesystem API should be sufficient for basic file and directory versioning support, Subversion wants more—and that is where libsvn_repos comes in."
11100 #: ../source/book.xml:15593
11101 msgid "The Subversion repository library (libsvn_repos) sits (logically speaking) atop the libsvn_fs API, providing additional functionality beyond that of the underlying versioned filesystem logic. It does not completely wrap each and every filesystem function—only certain major steps in the general cycle of filesystem activity are wrapped by the repository interface. Some of these include the creation and commit of Subversion transactions, and the modification of revision properties. These particular events are wrapped by the repository layer because they have hooks associated with them. A repository hook system is not strictly related to implementing a versioning filesystem, so it lives in the repository wrapper library."
11105 #: ../source/book.xml:15606
11106 msgid "The hooks mechanism is but one of the reasons for the abstraction of a separate repository library from the rest of the filesystem code. The libsvn_repos API provides several other important utilities to Subversion. These include the abilities to:"
11110 #: ../source/book.xml:15613
11111 msgid "create, open, destroy, and perform recovery steps on a Subversion repository and the filesystem included in that repository."
11115 #: ../source/book.xml:15618
11116 msgid "describe the differences between two filesystem trees."
11120 #: ../source/book.xml:15622
11121 msgid "query for the commit log messages associated with all (or some) of the revisions in which a set of files was modified in the filesystem."
11125 #: ../source/book.xml:15627
11126 msgid "generate a human-readable <quote>dump</quote> of the filesystem, a complete representation of the revisions in the filesystem."
11130 #: ../source/book.xml:15632
11131 msgid "parse that dump format, loading the dumped revisions into a different Subversion repository."
11135 #: ../source/book.xml:15636
11136 msgid "As Subversion continues to evolve, the repository library will grow with the filesystem library to offer increased functionality and configurable option support."
11140 #: ../source/book.xml:15643
11141 msgid "Repository Access Layer"
11145 #: ../source/book.xml:15645
11146 msgid "If the Subversion Repository Layer is at <quote>the other end of the line</quote>, the Repository Access (RA) Layer is the line itself. Charged with marshaling data between the client libraries and the repository, this layer includes the libsvn_ra module loader library, the RA modules themselves (which currently includes libsvn_ra_dav, libsvn_ra_local, libsvn_ra_serf, and libsvn_ra_svn), and any additional libraries needed by one or more of those RA modules (such as the mod_dav_svn Apache module or libsvn_ra_svn's server, <command>svnserve</command>)."
11150 #: ../source/book.xml:15655
11151 msgid "Since Subversion uses URLs to identify its repository resources, the protocol portion of the URL scheme (usually <literal>file://</literal>, <literal>http://</literal>, <literal>https://</literal>, <literal>svn://</literal>, or <literal>svn+ssh://</literal>) is used to determine which RA module will handle the communications. Each module registers a list of the protocols it knows how to <quote>speak</quote> so that the RA loader can, at runtime, determine which module to use for the task at hand. You can determine which RA modules are available to the Subversion command-line client, and what protocols they claim to support, by running <command>svn --version</command>:"
11155 #: ../source/book.xml:15667
11157 msgid "\n$ svn --version\nsvn, version 1.4.3 (r23084)\n compiled Jan 18 2007, 07:47:40\n\nCopyright (C) 2000-2006 CollabNet.\nSubversion is open source software, see http://subversion.tigris.org/\nThis product includes software developed by CollabNet (http://www.Collab.Net/).\n\nThe following repository access (RA) modules are available:\n\n* ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol.\n - handles 'http' scheme\n - handles 'https' scheme\n* ra_svn : Module for accessing a repository using the svn network protocol.\n - handles 'svn' scheme\n* ra_local : Module for accessing a repository on local disk.\n - handles 'file' scheme\n\n$\n"
11161 #: ../source/book.xml:15688
11162 msgid "The public API exported by the RA Layer contains functionality necessary for sending and receiving versioned data to and from the repository. And each of the available RA plugins is able to perform that task using a specific protocol—libsvn_ra_dav speaks HTTP/WebDAV (optionally using SSL encryption) with an Apache HTTP Server that is running the mod_dav_svn Subversion server module; libsvn_ra_svn speaks a custom network protocol with the <command>svnserve</command> program; and so on."
11166 #: ../source/book.xml:15697
11167 msgid "And for those who wish to access a Subversion repository using still another protocol, that is precisely why the Repository Access Layer is modularized! Developers can simply write a new library that implements the RA interface on one side and communicates with the repository on the other. Your new library can use existing network protocols, or you can invent your own. You could use inter-process communication (IPC) calls, or—let's get crazy, shall we?—you could even implement an email-based protocol. Subversion supplies the APIs; you supply the creativity."
11171 #: ../source/book.xml:15711
11172 msgid "Client Layer"
11176 #: ../source/book.xml:15713
11177 msgid "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 <quote>reflection</quote> of one or more repository locations—and propagating changes to and from the Repository Access layer."
11181 #: ../source/book.xml:15721
11182 msgid "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 <filename>.svn</filename>, 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 <filename>.svn</filename> subdirectory is similar in purpose to the <filename>CVS</filename> administrative directories found in CVS working copies. For more information about the <filename>.svn</filename> administrative area, see <xref linkend=\"svn.developer.insidewc\"/>in this chapter."
11186 #: ../source/book.xml:15734
11187 msgid "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 <function>svn_client_checkout()</function> 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 (<filename>.svn</filename> directories and all)."
11191 #: ../source/book.xml:15747
11192 msgid "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. In fact, the Subversion source code tree contains a small C program (which can be found at <filename>tools/examples/minimal_client.c</filename> that exemplifies how to wield the Subversion API to create a simple client program"
11196 #: ../source/book.xml:15762
11197 msgid "Binding Directly—A Word About Correctness"
11201 #: ../source/book.xml:15764
11202 msgid "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, it can be more correct 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."
11206 #: ../source/book.xml:15775
11207 msgid "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 <emphasis>again</emphasis> translate into <emphasis>its</emphasis> 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."
11211 #: ../source/book.xml:15784
11212 msgid "But the most compelling argument for binding directly to the APIs instead of wrapping other programs is that the Subversion project makes compatibility promises regarding its APIs. Across minor versions of those APIs (such as between 1.3 and 1.4), no function's prototype will change. In other words, you aren't forced to update your program's source code simply because you've upgraded to a new version of Subversion. Certain functions might be deprecated, but they still work, and this gives you a buffer of time to eventually embrace the newer APIs. These kinds of compatibility promises do not exist for Subversion command-line program output, which is subject to change from release to release."
11216 #: ../source/book.xml:15805
11217 msgid "Inside the Working Copy Administration Area"
11221 #: ../source/book.xml:15807
11222 msgid "As we mentioned earlier, each directory of a Subversion working copy contains a special subdirectory called <filename>.svn</filename> which houses administrative data about that working copy directory. Subversion uses the information in <filename>.svn</filename> to keep track of things like:"
11226 #: ../source/book.xml:15814
11227 msgid "Which repository location(s) are represented by the files and subdirectories in the working copy directory."
11231 #: ../source/book.xml:15819
11232 msgid "What revision of each of those files and directories are currently present in the working copy."
11236 #: ../source/book.xml:15823
11237 msgid "Any user-defined properties that might be attached to those files and directories."
11241 #: ../source/book.xml:15827
11242 msgid "Pristine (un-edited) copies of the working copy files."
11246 #: ../source/book.xml:15831
11247 msgid "The Subversion working copy administration area's layout and contents are considered implementation details not really intended for human consumption. Developers are encouraged to use Subversion's public APIs, or the tools that Subversion provides, to access and manipulate the working copy data, instead of directly reading or modifying those files. The file formats employed by the working copy library for its administrative data do change from time to time—a fact that the public APIs do a great job of hiding from the average user. In this section, we expose some of these implementation details sheerly to appease your overwhelming curiosity."
11251 #: ../source/book.xml:15845
11252 msgid "The Entries File"
11256 #: ../source/book.xml:15847
11257 msgid "Perhaps the single most important file in the <filename>.svn</filename> directory is the <filename>entries</filename> file. It contains the bulk of the administrative information about the versioned items in a working copy directory. It is this one file which tracks the repository URLs, pristine revision, file checksums, pristine text and property timestamps, scheduling and conflict state information, last-known commit information (author, revision, timestamp), local copy history—practically everything that a Subversion client is interested in knowing about a versioned (or to-be-versioned) resource!"
11261 #: ../source/book.xml:15859
11262 msgid "Folks familiar with CVS's administrative directories will have recognized at this point that Subversion's <filename>.svn/entries</filename> file serves the purposes of, among other things, CVS's <filename>CVS/Entries</filename>, <filename>CVS/Root</filename>, and <filename>CVS/Repository</filename> files combined."
11266 #: ../source/book.xml:15865
11267 msgid "The format of the <filename>.svn/entries</filename> file has changed over time. Originally an XML file, it now uses a custom—though still human-readable—file format. While XML was a great choice for early developers of Subversion who were frequently debugging the file's contents (and Subversion's behavior in light of them), the need for easy developer debugging has diminished as Subversion has matured, and has been replaced by the user's need for snappier performance. Be aware that Subversion's working copy library automatically upgrades working copies from one format to another—it reads the old formats, and writes the new—which saves you the hassle of checking out a new working copy, but can also complicate situations where different versions of Subversion might be trying to use the same working copy."
11271 #: ../source/book.xml:15884
11272 msgid "Pristine Copies and Property Files"
11276 #: ../source/book.xml:15886
11277 msgid "As mentioned before, the <filename>.svn</filename> directory also holds the pristine <quote>text-base</quote> versions of files. Those can be found in <filename>.svn/text-base</filename>. The benefits of these pristine copies are multiple—network-free checks for local modifications and difference reporting, network-free reversion of modified or missing files, more efficient transmission of changes to the server—but comes at the cost of having each versioned file stored at least twice on disk. These days, this seems to be a negligible penalty for most files. However, the situation gets uglier as the size of your versioned files grows. Some attention is being given to making the presence of the <quote>text-base</quote> an option. Ironically though, it is as your versioned files' sizes get larger that the existence of the <quote>text-base</quote> becomes more crucial—who wants to transmit a huge file across a network just because they want to commit a tiny change to it?"
11281 #: ../source/book.xml:15904
11282 msgid "Similar in purpose to the <quote>text-base</quote> files are the property files and their pristine <quote>prop-base</quote> copies, located in <filename>.svn/props</filename> and <filename>.svn/prop-base</filename> respectively. Since directories can have properties, too, there are also <filename>.svn/dir-props</filename> and <filename>.svn/dir-prop-base</filename> files."
11286 #: ../source/book.xml:15919
11287 msgid "Using the APIs"
11291 #: ../source/book.xml:15921
11292 msgid "Developing applications against the Subversion library APIs is fairly straightforward. Subversion is primarily a set of C libraries, with header (.h) files that live in the <filename>subversion/include</filename> directory of the source tree. These headers are copied into your system locations (for example, <filename>/usr/local/include</filename>) when you build and install Subversion itself from source. These headers represent the entirety of the functions and types meant to be accessible by users of the Subversion libraries. The Subversion developer community is meticulous about ensuring that the public API is well-documented—refer directly to the header files for that documentation."
11296 #: ../source/book.xml:15933
11297 msgid "When examining the public header files, the first thing you might notice is that Subversion's datatypes and functions are namespace protected. That is, every public Subversion symbol name begins with <literal>svn_</literal>, followed by a short code for the library in which the symbol is defined (such as <literal>wc</literal>, <literal>client</literal>, <literal>fs</literal>, etc.), followed by a single underscore (<literal>_</literal>) and then the rest of the symbol name. Semi-public functions (used among source files of a given library but not by code outside that library, and found inside the library directories themselves) differ from this naming scheme in that instead of a single underscore after the library code, they use a double underscore (<literal>__</literal>). Functions that are private to a given source file have no special prefixing, and are declared <literal>static</literal>. Of course, a compiler isn't interested in these naming conventions, but they help to clarify the scope of a given function or datatype."
11301 #: ../source/book.xml:15958
11302 msgid "After all, Subversion uses Subversion's APIs, too."
11306 #: ../source/book.xml:15951
11307 msgid "Another good source of information about programming against the Subversion APIs is the project's own hacking guidelines, which can be found at <uri href=\"http://subversion.tigris.org/hacking.html\">http://subversion.tigris.org/hacking.html</uri>. This document contains useful information which, while aimed at developers and would-be developers of Subversion itself, is equally applicable to folks developing against Subversion as a set of third-party libraries. <placeholder-1/>"
11311 #: ../source/book.xml:15964
11312 msgid "The Apache Portable Runtime Library"
11316 #: ../source/book.xml:15966
11317 msgid "Along with Subversion's own datatypes, you will see many references to datatypes that begin with <literal>apr_</literal>—symbols from the Apache Portable Runtime (APR) library. APR is Apache's portability library, originally carved out of its server code as an attempt to separate the OS-specific bits from the OS-independent portions of the code. The result was a library that provides a generic API for performing operations that differ mildly—or wildly—from OS to OS. While the Apache HTTP Server was obviously the first user of the APR library, the Subversion developers immediately recognized the value of using APR as well. This means that there is practically no OS-specific code in Subversion itself. Also, it means that the Subversion client compiles and runs anywhere that Apache HTTP Server itself does. Currently this list includes all flavors of Unix, Win32, BeOS, OS/2, and Mac OS X."
11321 #: ../source/book.xml:15984
11322 msgid "Subversion uses ANSI system calls and datatypes as much as possible."
11326 #: ../source/book.xml:15995
11327 msgid "Neon and Berkeley DB are examples of such libraries."
11331 #: ../source/book.xml:15982
11332 msgid "In addition to providing consistent implementations of system calls that differ across operating systems, <placeholder-1/> APR gives Subversion immediate access to many custom datatypes, such as dynamic arrays and hash tables. Subversion uses these types extensively. But perhaps the most pervasive APR datatype, found in nearly every Subversion API prototype, is the apr_pool_t — the APR memory pool. Subversion uses pools internally for all its memory allocation needs (unless an external library requires a different memory management mechanism for data passed through its API), <placeholder-2/> and while a person coding against the Subversion APIs is not required to do the same, they <emphasis>are</emphasis> required to provide pools to the API functions that need them. This means that users of the Subversion API must also link against APR, must call <function>apr_initialize()</function> to initialize the APR subsystem, and then must create and manage pools for use with Subversion API calls, typically by using <function>svn_pool_create()</function>, <function>svn_pool_clear()</function>, and <function>svn_pool_destroy()</function>."
11336 #: ../source/book.xml:16008
11337 msgid "Programming with Memory Pools"
11341 #: ../source/book.xml:16010
11342 msgid "Almost every developer who has used the C programming language has at some point sighed at the daunting task of managing memory usage. Allocating enough memory to use, keeping track of those allocations, freeing the memory when you no longer need it—these tasks can be quite complex. And of course, failure to do those things properly can result in a program that crashes itself, or worse, crashes the computer."
11346 #: ../source/book.xml:16020
11347 msgid "Or at least make it something you only toy with when doing extremely tight program optimization."
11351 #: ../source/book.xml:16018
11352 msgid "Higher-level languages, on the other hand, take the job of memory management away from the developer completely. <placeholder-1/> Languages like Java and Python use <firstterm>garbage collection</firstterm>, allocating memory for objects when needed, and automatically freeing that memory when the object is no longer in use."
11356 #: ../source/book.xml:16026
11357 msgid "APR provides a middle-ground approach called pool-based memory management. It allows the developer to control memory usage at a lower resolution—per chunk (or <quote>pool</quote>) of memory, instead of per allocated object. Rather than using <function>malloc()</function> and friends to allocate enough memory for a given object, you ask APR to allocate the memory from a memory pool. When you're finished using the objects you've created in the pool, you destroy the entire pool, effectively de-allocating the memory consumed by <emphasis>all</emphasis> the objects you allocated from it. Thus, rather than keeping track of individual objects which need to be de-allocated, your program simply considers the general lifetimes of those objects, and allocates the objects in a pool whose lifetime (the time between the pool's creation and its deletion) matches the object's needs."
11361 #: ../source/book.xml:16047
11362 msgid "URL and Path Requirements"
11366 #: ../source/book.xml:16049
11367 msgid "With remote version control operation as the whole point of Subversion's existence, it makes sense that some attention has been paid to internationalization (i18n) support. After all, while <quote>remote</quote> might mean <quote>across the office</quote>, it could just as well mean <quote>across the globe.</quote> To facilitate this, all of Subversion's public interfaces that accept path arguments expect those paths to be canonicalized, and encoded in UTF-8. This means, for example, that any new client binary that drives the libsvn_client interface needs to first convert paths from the locale-specific encoding to UTF-8 before passing those paths to the Subversion libraries, and then re-convert any resultant output paths from Subversion back into the locale's encoding before using those paths for non-Subversion purposes. Fortunately, Subversion provides a suite of functions (see <filename>subversion/include/svn_utf.h</filename>) that can be used by any program to do these conversions."
11371 #: ../source/book.xml:16066
11372 msgid "Also, Subversion APIs require all URL parameters to be properly URI-encoded. So, instead of passing <uri>file:///home/username/My File.txt</uri> as the URL of a file named <literal>My File.txt</literal>, you need to pass <uri>file:///home/username/My%20File.txt</uri>. Again, Subversion supplies helper functions that your application can use—<function>svn_path_uri_encode()</function> and <function>svn_path_uri_decode()</function>, for URI encoding and decoding, respectively."
11376 #: ../source/book.xml:16079
11377 msgid "Using Languages Other than C and C++"
11381 #: ../source/book.xml:16081
11382 msgid "If you are interested in using the Subversion libraries in conjunction with something other than a C program—say a Python or Perl script—Subversion has some support for this via the Simplified Wrapper and Interface Generator (SWIG). The SWIG bindings for Subversion are located in <filename>subversion/bindings/swig</filename>. They are still maturing, but they are usable. These bindings allow you to call Subversion API functions indirectly, using wrappers that translate the datatypes native to your scripting language into the datatypes needed by Subversion's C libraries."
11386 #: ../source/book.xml:16091
11387 msgid "Significant efforts have been made towards creating functional SWIG-generated bindings for Python, Perl, and Ruby. To some extent, the work done preparing the SWIG interface files for these languages is reusable in efforts to generate bindings for other languages supported by SWIG (which include versions of C#, Guile, Java, MzScheme, OCaml, PHP, and Tcl, among others). However, some extra programming is required to compensate for complex APIs that SWIG needs some help translating between languages. For more information on SWIG itself, see the project's website at <uri href=\"http://www.swig.org/\">http://www.swig.org/</uri>."
11391 #: ../source/book.xml:16101
11392 msgid "Subversion also has language bindings for Java. The JavaJL bindings (located in <filename>subversion/bindings/java</filename> in the Subversion source tree) aren't SWIG-based, but are instead a mixture of javah and hand-coded JNI. JavaHL most covers Subversion client-side APIs, and is specifically targeted at implementors of Java-based Subversion clients and IDE integrations."
11396 #: ../source/book.xml:16109
11397 msgid "Subversion's language bindings tend to lack the level of developer attention given to the core Subversion modules, but can generally be trusted as production-ready. A number of scripts and applications, alternative Subversion GUI clients and other third-party tools are successfully using Subversion's language bindings today to accomplish their Subversion integrations."
11401 #: ../source/book.xml:16116
11402 msgid "It's worth noting here that there are other options for interfacing with Subversion using other languages: alternative bindings for Subversion which aren't provided by the Subversion development community at all. You can find links to these alternative bindings on the Subversion project's links page (at <uri href=\"http://subversion.tigris.org/links.html\">http://subversion.tigris.org/links.html</uri>), but there are a couple of popular ones we feel are especially noteworthy. First, Barry Scott's PySVN bindings (<uri href=\"http://pysvn.tigris.org/\">http://pysvn.tigris.org/</uri>) are a popular option for binding with Python. PySVN boasts of a more Pythonic interface than the more C-like APIs provided by Subversion's own Python bindings. For folks looking for a pure Java implementation of Subversion, check out SVNKit (<uri href=\"http://svnkit.com/\">http://svnkit.com/</uri>), which is Subversion re-written from the ground up in Java. You should exercise caution here, though—because SVNKit doesn't use the core Subversion libraries, it's behavior is not guaranteed to match that of Subversion itself."
11406 #: ../source/book.xml:16136
11407 msgid "Code Samples"
11411 #: ../source/book.xml:16138
11412 msgid "<xref linkend=\"svn.developer.layerlib.repos.ex-1\"/> contains a code segment (written in C) that illustrates some of the concepts we've been discussing. It uses both the repository and filesystem interfaces (as can be determined by the prefixes <literal>svn_repos_</literal> and <literal>svn_fs_</literal> of the function names, respectively) to create a new revision in which a directory is added. You can see the use of an APR pool, which is passed around for memory allocation purposes. Also, the code reveals a somewhat obscure fact about Subversion error handling—all Subversion errors must be explicitly handled to avoid memory leakage (and in some cases, application failure)."
11416 #: ../source/book.xml:16153
11417 msgid "Using the Repository Layer"
11421 #: ../source/book.xml:16155
11423 msgid "\n/* Convert a Subversion error into a simple boolean error code.\n *\n * NOTE: Subversion errors must be cleared (using svn_error_clear())\n * because they are allocated from the global pool, else memory\n * leaking occurs.\n */\n#define INT_ERR(expr) \\\n do { \\\n svn_error_t *__temperr = (expr); \\\n if (__temperr) \\\n { \\\n svn_error_clear(__temperr); \\\n return 1; \\\n } \\\n return 0; \\\n } while (0)\n\n/* Create a new directory at the path NEW_DIRECTORY in the Subversion\n * repository located at REPOS_PATH. Perform all memory allocation in\n * POOL. This function will create a new revision for the addition of\n * NEW_DIRECTORY. Return zero if the operation completes\n * successfully, non-zero otherwise.\n */\nstatic int\nmake_new_directory(const char *repos_path,\n const char *new_directory,\n apr_pool_t *pool)\n{\n svn_error_t *err;\n svn_repos_t *repos;\n svn_fs_t *fs;\n svn_revnum_t youngest_rev;\n svn_fs_txn_t *txn;\n svn_fs_root_t *txn_root;\n const char *conflict_str;\n\n /* Open the repository located at REPOS_PATH. \n */\n INT_ERR(svn_repos_open(&repos, repos_path, pool));\n\n /* Get a pointer to the filesystem object that is stored in REPOS. \n */\n fs = svn_repos_fs(repos);\n\n /* Ask the filesystem to tell us the youngest revision that\n * currently exists. \n */\n INT_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));\n\n /* Begin a new transaction that is based on YOUNGEST_REV. We are\n * less likely to have our later commit rejected as conflicting if we\n * always try to make our changes against a copy of the latest snapshot\n * of the filesystem tree. \n */\n INT_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));\n\n /* Now that we have started a new Subversion transaction, get a root\n * object that represents that transaction. \n */\n INT_ERR(svn_fs_txn_root(&txn_root, txn, pool));\n \n /* Create our new directory under the transaction root, at the path\n * NEW_DIRECTORY. \n */\n INT_ERR(svn_fs_make_dir(txn_root, new_directory, pool));\n\n /* Commit the transaction, creating a new revision of the filesystem\n * which includes our added directory path.\n */\n err = svn_repos_fs_commit_txn(&conflict_str, repos, \n &youngest_rev, txn, pool);\n if (! err)\n {\n /* No error? Excellent! Print a brief report of our success.\n */\n printf(\"Directory '%s' was successfully added as new revision \"\n \"'%ld'.\\n\", new_directory, youngest_rev);\n }\n else if (err->apr_err == SVN_ERR_FS_CONFLICT)\n {\n /* Uh-oh. Our commit failed as the result of a conflict\n * (someone else seems to have made changes to the same area \n * of the filesystem that we tried to modify). Print an error\n * message.\n */\n printf(\"A conflict occurred at path '%s' while attempting \"\n \"to add directory '%s' to the repository at '%s'.\\n\", \n conflict_str, new_directory, repos_path);\n }\n else\n {\n /* Some other error has occurred. Print an error message.\n */\n printf(\"An error occurred while attempting to add directory '%s' \"\n \"to the repository at '%s'.\\n\", \n new_directory, repos_path);\n }\n\n INT_ERR(err);\n} \n"
11427 #: ../source/book.xml:16258
11428 msgid "Note that in <xref linkend=\"svn.developer.layerlib.repos.ex-1\"/>, the code could just as easily have committed the transaction using <function>svn_fs_commit_txn()</function>. But the filesystem API knows nothing about the repository library's hook mechanism. If you want your Subversion repository to automatically perform some set of non-Subversion tasks every time you commit a transaction (like, for example, sending an email that describes all the changes made in that transaction to your developer mailing list), you need to use the libsvn_repos-wrapped version of that function, which adds the hook triggering functionality—in this case, <function>svn_repos_fs_commit_txn()</function>. (For more information regarding Subversion's repository hooks, see <xref linkend=\"svn.reposadmin.create.hooks\"/>.)"
11432 #: ../source/book.xml:16271
11433 msgid "Now let's switch languages. <xref linkend=\"svn.developer.usingapi.otherlangs.ex-1\"/> is a sample program that uses Subversion's SWIG Python bindings to recursively crawl the youngest repository revision, and print the various paths reached during the crawl."
11437 #: ../source/book.xml:16277
11438 msgid "Using the Repository Layer with Python"
11442 #: ../source/book.xml:16279
11444 msgid "\n#!/usr/bin/python\n\n\"\"\"Crawl a repository, printing versioned object path names.\"\"\"\n\nimport sys\nimport os.path\nimport svn.fs, svn.core, svn.repos\n\ndef crawl_filesystem_dir(root, directory):\n \"\"\"Recursively crawl DIRECTORY under ROOT in the filesystem, and return\n a list of all the paths at or below DIRECTORY.\"\"\"\n\n # Print the name of this path.\n print directory + \"/\"\n \n # Get the directory entries for DIRECTORY.\n entries = svn.fs.svn_fs_dir_entries(root, directory)\n\n # Loop over the entries.\n names = entries.keys()\n for name in names:\n # Calculate the entry's full path.\n full_path = directory + '/' + name\n\n # If the entry is a directory, recurse. The recursion will return\n # a list with the entry and all its children, which we will add to\n # our running list of paths.\n if svn.fs.svn_fs_is_dir(root, full_path):\n crawl_filesystem_dir(root, full_path)\n else:\n # Else it's a file, so print its path here.\n print full_path\n\ndef crawl_youngest(repos_path):\n \"\"\"Open the repository at REPOS_PATH, and recursively crawl its\n youngest revision.\"\"\"\n \n # Open the repository at REPOS_PATH, and get a reference to its\n # versioning filesystem.\n repos_obj = svn.repos.svn_repos_open(repos_path)\n fs_obj = svn.repos.svn_repos_fs(repos_obj)\n\n # Query the current youngest revision.\n youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj)\n \n # Open a root object representing the youngest (HEAD) revision.\n root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev)\n\n # Do the recursive crawl.\n crawl_filesystem_dir(root_obj, \"\")\n \nif __name__ == \"__main__\":\n # Check for sane usage.\n if len(sys.argv) != 2:\n sys.stderr.write(\"Usage: %s REPOS_PATH\\n\"\n % (os.path.basename(sys.argv[0])))\n sys.exit(1)\n\n # Canonicalize the repository path.\n repos_path = svn.core.svn_path_canonicalize(sys.argv[1])\n\n # Do the real work.\n crawl_youngest(repos_path)\n"
11448 #: ../source/book.xml:16345
11449 msgid "This same program in C would need to deal with APR's memory pool system. But Python handles memory usage automatically, and Subversion's Python bindings adhere to that convention. In C, you'd be working with custom datatypes (such as those provided by the APR library) for representing the hash of entries and the list of paths, but Python has hashes (called <quote>dictionaries</quote>) and lists as built-in datatypes, and provides a rich collection of functions for operating on those types. So SWIG (with the help of some customizations in Subversion's language bindings layer) takes care of mapping those custom datatypes into the native datatypes of the target language. This provides a more intuitive interface for users of that language."
11453 #: ../source/book.xml:16358
11454 msgid "The Subversion Python bindings can be used for working copy operations, too. In the previous section of this chapter, we mentioned the <filename>libsvn_client</filename> interface, and how it exists for the sole purpose of simplifying the process of writing a Subversion client. <xref linkend=\"svn.developer.usingapi.otherlangs.ex-2\"/> is a brief example of how that library can be accessed via the SWIG Python bindings to recreate a scaled-down version of the <command>svn status</command> command."
11458 #: ../source/book.xml:16368
11459 msgid "A Python Status Crawler"
11463 #: ../source/book.xml:16370
11465 msgid "\n#!/usr/bin/env python\n\n\"\"\"Crawl a working copy directory, printing status information.\"\"\"\n\nimport sys\nimport os.path\nimport getopt\nimport svn.core, svn.client, svn.wc\n\ndef generate_status_code(status):\n \"\"\"Translate a status value into a single-character status code,\n using the same logic as the Subversion command-line client.\"\"\"\n code_map = { svn.wc.svn_wc_status_none : ' ',\n svn.wc.svn_wc_status_normal : ' ',\n svn.wc.svn_wc_status_added : 'A',\n svn.wc.svn_wc_status_missing : '!',\n svn.wc.svn_wc_status_incomplete : '!',\n svn.wc.svn_wc_status_deleted : 'D',\n svn.wc.svn_wc_status_replaced : 'R',\n svn.wc.svn_wc_status_modified : 'M',\n svn.wc.svn_wc_status_merged : 'G',\n svn.wc.svn_wc_status_conflicted : 'C',\n svn.wc.svn_wc_status_obstructed : '~',\n svn.wc.svn_wc_status_ignored : 'I',\n svn.wc.svn_wc_status_external : 'X',\n svn.wc.svn_wc_status_unversioned : '?',\n }\n return code_map.get(status, '?')\n\ndef do_status(wc_path, verbose):\n # Calculate the length of the input working copy path.\n wc_path_len = len(wc_path)\n\n # Build a client context baton.\n ctx = svn.client.svn_client_ctx_t()\n\n def _status_callback(path, status, root_path_len=wc_path_len):\n \"\"\"A callback function for svn_client_status.\"\"\"\n\n # Print the path, minus the bit that overlaps with the root of\n # the status crawl\n text_status = generate_status_code(status.text_status)\n prop_status = generate_status_code(status.prop_status)\n print '%s%s %s' % (text_status, prop_status, path[wc_path_len + 1:])\n \n # Do the status crawl, using _status_callback() as our callback function.\n svn.client.svn_client_status(wc_path, None, _status_callback,\n 1, verbose, 0, 0, ctx)\n\ndef usage_and_exit(errorcode):\n \"\"\"Print usage message, and exit with ERRORCODE.\"\"\"\n stream = errorcode and sys.stderr or sys.stdout\n stream.write(\"\"\"Usage: %s OPTIONS WC-PATH\nOptions:\n --help, -h : Show this usage message\n --verbose, -v : Show all statuses, even uninteresting ones\n\"\"\" % (os.path.basename(sys.argv[0])))\n sys.exit(errorcode)\n \nif __name__ == '__main__':\n # Parse command-line options.\n try:\n opts, args = getopt.getopt(sys.argv[1:], \"hv\", [\"help\", \"verbose\"])\n except getopt.GetoptError:\n usage_and_exit(1)\n verbose = 0\n for opt, arg in opts:\n if opt in (\"-h\", \"--help\"):\n usage_and_exit(0)\n if opt in (\"-v\", \"--verbose\"):\n verbose = 1\n if len(args) != 1:\n usage_and_exit(2)\n \n # Canonicalize the repository path.\n wc_path = svn.core.svn_path_canonicalize(args[0])\n\n # Do the real work.\n try:\n do_status(wc_path, verbose)\n except svn.core.SubversionException, e:\n sys.stderr.write(\"Error (%d): %s\\n\" % (e[1], e[0]))\n sys.exit(1)\n"
11469 #: ../source/book.xml:16456
11470 msgid "As was the case in <xref linkend=\"svn.developer.usingapi.otherlangs.ex-1\"/>, this program is pool-free and uses, for the most part, normal Python data types. The call to <function>svn_client_ctx_t()</function> is deceiving because the public Subversion API has no such function—this just happens to be a case where SWIG's automatic language generation bleeds through a little bit (the function is a sort of factory function for Python's version of the corresponding complex C structure). Also note that the path passed to this program (like the last one) gets run through <function>svn_path_canonicalize()</function>, because to <emphasis>not</emphasis> do so runs the risk of triggering the underlying Subversion C library's assertions about such things, which translate into rather immediate and unceremonious program abortion."
11474 #: ../source/book.xml:16481
11475 msgid "Subversion Complete Reference"
11479 #: ../source/book.xml:16483
11480 msgid "This chapter is intended to be a complete reference to using Subversion. This includes the command line client (<command>svn</command>) and all its subcommands, as well as the repository administration programs (<command>svnadmin</command> and <command>svnlook</command>) and their respective subcommands."
11484 #: ../source/book.xml:16494
11485 msgid "The Subversion Command Line Client: <command>svn</command>"
11489 #: ../source/book.xml:16498
11490 msgid "Yes, yes, you don't need a subcommand to use the <option>--version</option> option, but we'll get to that in just a minute."
11494 #: ../source/book.xml:16496
11495 msgid "To use the command line client, you type <command>svn</command>, the subcommand you wish to use <placeholder-1/>, and any options or targets that you wish to operate on—there is no specific order that the subcommand and the options must appear in. For example, all of the following are valid ways to use <command>svn status</command>:"
11499 #: ../source/book.xml:16505
11501 msgid "\n$ svn -v status\n$ svn status -v \n$ svn status -v myfile\n"
11505 #: ../source/book.xml:16510
11506 msgid "You can find many more examples of how to use most client commands in <xref linkend=\"svn.tour\"/> and commands for managing properties in <xref linkend=\"svn.advanced.props\"/>."
11510 #: ../source/book.xml:16516
11511 msgid "<command>svn</command> Options"
11515 #: ../source/book.xml:16518
11516 msgid "While Subversion has different options for its subcommands, all options are global—that is, each option is guaranteed to mean the same thing regardless of the subcommand you use it with. For example, <option>--verbose</option> (<option>-v</option>) always means <quote>verbose output</quote>, regardless of the subcommand you use it with."
11520 #: ../source/book.xml:16528
11521 msgid "--auto-props"
11525 #: ../source/book.xml:16531
11526 msgid "Enables auto-props, overriding the <literal>enable-auto-props</literal> directive in the <filename>config</filename> file."
11530 #: ../source/book.xml:16537
11531 msgid "<option>--change</option> (<option>-c</option>) <replaceable>ARG</replaceable>"
11535 #: ../source/book.xml:16540
11536 msgid "Used as a means to refer to a specific <quote>change</quote> (aka a revision), this option is syntactic sugar for <quote>-r ARG-1:ARG</quote>."
11540 #: ../source/book.xml:16547 ../source/book.xml:22670
11541 msgid "--config-dir"
11545 #: ../source/book.xml:16548 ../source/book.xml:20876 ../source/book.xml:22671
11550 #: ../source/book.xml:16551 ../source/book.xml:22674
11551 msgid "Instructs Subversion to read configuration information from the specified directory instead of the default location (<filename>.subversion</filename> in the user's home directory)."
11555 #: ../source/book.xml:16559
11560 #: ../source/book.xml:16560 ../source/book.xml:16578 ../source/book.xml:16597
11565 #: ../source/book.xml:16563
11566 msgid "Specifies an external program to use to show differences between files. When <command>svn diff</command> is invoked without this option, it uses Subversion's internal diff engine, which provides unified diffs by default. If you want to use an external diff program, use <option>--diff-cmd</option>. You can pass options to the diff program with the <option>--extensions</option> option (more on that later in this section)."
11570 #: ../source/book.xml:16577
11571 msgid "--diff3-cmd"
11575 #: ../source/book.xml:16581
11576 msgid "Specifies an external program to use to merge files."
11580 #: ../source/book.xml:16586
11585 #: ../source/book.xml:16589
11586 msgid "Goes through all the motions of running a command, but makes no actual changes—either on disk or in the repository."
11590 #: ../source/book.xml:16596
11591 msgid "--editor-cmd"
11595 #: ../source/book.xml:16600
11596 msgid "Specifies an external program to use to edit a log message or a property value. See the <literal>editor-cmd</literal> section in <xref linkend=\"svn.advanced.confarea.opts.config\"/> for ways to specify a default editor."
11600 #: ../source/book.xml:16608
11605 #: ../source/book.xml:16609
11610 #: ../source/book.xml:16612
11611 msgid "Tells Subversion that your commit message is encoded in the charset provided. The default is your operating system's native locale, and you should specify the encoding if your commit message is in any other encoding."
11615 #: ../source/book.xml:16620
11616 msgid "<option>--extensions</option> (<option>-x</option>) <replaceable>ARGS</replaceable>"
11620 #: ../source/book.xml:16623
11621 msgid "Specifies an argument or arguments that Subversion should pass to an external diff command. This option is valid only when used with the <command>svn diff</command> or <command>svn merge</command> commands, with the <option>--diff-cmd</option> option. If you wish to pass multiple arguments, you must enclose all of them in quotes (for example, <command>svn diff --diff-cmd /usr/bin/diff -x \"-b -E\"</command>)."
11625 #: ../source/book.xml:16636
11626 msgid "<option>--file</option> (<option>-F</option>) <replaceable>FILENAME</replaceable>"
11630 #: ../source/book.xml:16640
11631 msgid "Uses the contents of the named file for the specified subcommand, though different subcommands do different things with this content. For example, <command>svn commit</command> uses the content as a commit log, whereas <command>svn propset</command> uses it as a property value."
11635 #: ../source/book.xml:16650
11640 #: ../source/book.xml:16653
11641 msgid "Forces a particular command or operation to run. There are some operations that Subversion will prevent you from doing in normal usage, but you can pass the force option to tell Subversion <quote>I know what I'm doing as well as the possible repercussions of doing it, so let me at 'em</quote>. This option is the programmatic equivalent of doing your own electrical work with the power on—if you don't know what you're doing, you're likely to get a nasty shock."
11645 #: ../source/book.xml:16666
11646 msgid "--force-log"
11650 #: ../source/book.xml:16669
11651 msgid "Forces a suspicious parameter passed to the <option>--message</option> (<option>-m</option>) or <option>--file</option> (<option>-F</option>) options to be accepted as valid. By default, Subversion will produce an error if parameters to these options look like they might instead be targets of the subcommand. For example, if you pass a versioned file's path to the <option>--file</option> (<option>-F</option>) option, Subversion will assume you've made a mistake, that the path was instead intended as the target of the operation, and that you simply failed to provide some other—unversioned—file as the source of your log message. To assert your intent and override these types of errors, pass the <option>--force-log</option> option to subcommands that accept log messages."
11655 #: ../source/book.xml:16687
11656 msgid "<option>--help</option> (<option>-h</option> or <option>-?</option>)"
11660 #: ../source/book.xml:16691
11661 msgid "If used with one or more subcommands, shows the built-in help text for each subcommand. If used alone, it displays the general client help text."
11665 #: ../source/book.xml:16698
11666 msgid "--ignore-ancestry"
11670 #: ../source/book.xml:16701
11671 msgid "Tells Subversion to ignore ancestry when calculating differences (rely on path contents alone)."
11675 #: ../source/book.xml:16707
11676 msgid "--ignore-externals"
11680 #: ../source/book.xml:16710
11681 msgid "Tells Subversion to ignore external definitions and the external working copies managed by them."
11685 #: ../source/book.xml:16716 ../source/book.xml:20865
11686 msgid "--incremental"
11690 #: ../source/book.xml:16719
11691 msgid "Prints output in a format suitable for concatenation."
11695 #: ../source/book.xml:16725
11700 #: ../source/book.xml:16726
11705 #: ../source/book.xml:16729
11706 msgid "Show only the first <replaceable>NUM</replaceable> log messages."
11710 #: ../source/book.xml:16734
11711 msgid "<option>--message</option> (<option>-m</option>) <replaceable>MESSAGE</replaceable>"
11715 #: ../source/book.xml:16738
11716 msgid "Indicates that you will specify a either a log message or a lock comment on the command line, following this option. For example:"
11720 #: ../source/book.xml:16741
11722 msgid "\n$ svn commit -m \"They don't make Sunday.\"\n"
11726 #: ../source/book.xml:16748
11731 #: ../source/book.xml:16749 ../source/book.xml:16846
11736 #: ../source/book.xml:16752
11737 msgid "Uses <replaceable>ARG</replaceable> as the newer target (for use with <command>svn diff</command>)."
11741 #: ../source/book.xml:16758 ../source/book.xml:22682
11742 msgid "--no-auth-cache"
11746 #: ../source/book.xml:16761 ../source/book.xml:22685
11747 msgid "Prevents caching of authentication information (e.g. username and password) in the Subversion administrative directories."
11751 #: ../source/book.xml:16768
11752 msgid "--no-auto-props"
11756 #: ../source/book.xml:16771
11757 msgid "Disables auto-props, overriding the <literal>enable-auto-props</literal> directive in the <filename>config</filename> file."
11761 #: ../source/book.xml:16778 ../source/book.xml:21741
11762 msgid "--no-diff-deleted"
11766 #: ../source/book.xml:16781
11767 msgid "Prevents Subversion from printing differences for deleted files. The default behavior when you remove a file is for <command>svn diff</command> to print the same differences that you would see if you had left the file but removed all the content."
11771 #: ../source/book.xml:16790
11772 msgid "--no-ignore"
11776 #: ../source/book.xml:16793
11777 msgid "Shows files in the status listing that would normally be omitted since they match a pattern in the <literal>global-ignores</literal> configuration option or the <literal>svn:ignore</literal> property. See <xref linkend=\"svn.advanced.confarea.opts.config\"/> and <xref linkend=\"svn.advanced.props.special.ignore\"/> for more information."
11781 #: ../source/book.xml:16802
11782 msgid "--no-unlock"
11786 #: ../source/book.xml:16805
11787 msgid "Don't automatically unlock files (the default commit behavior is to unlock all files listed as part of the commit). See <xref linkend=\"svn.advanced.locking\"/> for more information."
11791 #: ../source/book.xml:16813 ../source/book.xml:22692
11792 msgid "--non-interactive"
11796 #: ../source/book.xml:16816 ../source/book.xml:22695
11797 msgid "In the case of an authentication failure, or insufficient credentials, prevents prompting for credentials (e.g. username or password). This is useful if you're running Subversion inside of an automated script and it's more appropriate to have Subversion fail than to prompt for more information."
11801 #: ../source/book.xml:16825
11802 msgid "<option>--non-recursive</option> (<option>-N</option>)"
11806 #: ../source/book.xml:16827
11807 msgid "Stops a subcommand from recursing into subdirectories. Most subcommands recurse by default, but some subcommands—usually those that have the potential to remove or undo your local modifications—do not."
11811 #: ../source/book.xml:16836
11812 msgid "--notice-ancestry"
11816 #: ../source/book.xml:16839
11817 msgid "Pay attention to ancestry when calculating differences."
11821 #: ../source/book.xml:16845
11826 #: ../source/book.xml:16849
11827 msgid "Uses <replaceable>ARG</replaceable> as the older target (for use with <command>svn diff</command>)."
11831 #: ../source/book.xml:16855 ../source/book.xml:22705
11836 #: ../source/book.xml:16856 ../source/book.xml:22706
11841 #: ../source/book.xml:16859 ../source/book.xml:22709
11842 msgid "Indicates that you are providing your password for authentication on the command line—otherwise, if it is needed, Subversion will prompt you for it."
11846 #: ../source/book.xml:16866
11847 msgid "<option>--quiet</option> (<option>-q</option>)"
11851 #: ../source/book.xml:16868
11852 msgid "Requests that the client print only essential information while performing an operation."
11856 #: ../source/book.xml:16873
11857 msgid "<option>--recursive</option> (<option>-R</option>)"
11861 #: ../source/book.xml:16875
11862 msgid "Makes a subcommand recurse into subdirectories. Most subcommands recurse by default."
11866 #: ../source/book.xml:16881
11871 #: ../source/book.xml:16882
11872 msgid "FROM TO [PATH...]"
11876 #: ../source/book.xml:16886
11877 msgid "Used with the <command>svn switch</command> subcommand, changes the location of the repository that your working copy references. This is useful if the location of your repository changes and you have an existing working copy that you'd like to continue to use. See <command>svn switch</command> for an example."
11881 #: ../source/book.xml:16896
11882 msgid "<option>--revision</option> (<option>-r</option>) <replaceable>REV</replaceable>"
11886 #: ../source/book.xml:16900
11887 msgid "Indicates that you're going to supply a revision (or range of revisions) for a particular operation. You can provide revision numbers, revision keywords or dates (in curly braces), as arguments to the revision option. If you wish to provide a range of revisions, you can provide two revisions separated by a colon. For example:"
11891 #: ../source/book.xml:16907
11893 msgid "\n$ svn log -r 1729\n$ svn log -r 1729:HEAD\n$ svn log -r 1729:1744\n$ svn log -r {2001-12-04}:{2002-02-17}\n$ svn log -r 1729:{2002-02-17}\n"
11897 #: ../source/book.xml:16914
11898 msgid "See <xref linkend=\"svn.tour.revs.keywords\"/> for more information."
11902 #: ../source/book.xml:16920 ../source/book.xml:21773
11907 #: ../source/book.xml:16923 ../source/book.xml:21776
11908 msgid "Operates on a revision property instead of a property specific to a file or directory. This option requires that you also pass a revision with the <option>--revision</option> (<option>-r</option>) option."
11912 #: ../source/book.xml:16931
11913 msgid "<option>--show-updates</option> (<option>-u</option>)"
11917 #: ../source/book.xml:16933
11918 msgid "Causes the client to display information about which files in your working copy are out-of-date. This doesn't actually update any of your files—it just shows you which files will be updated if you run <command>svn update</command>."
11922 #: ../source/book.xml:16943
11923 msgid "--stop-on-copy"
11927 #: ../source/book.xml:16946
11928 msgid "Causes a Subversion subcommand which is traversing the history of a versioned resource to stop harvesting that historical information when a copy—that is, a location in history where that resource was copied from another location in the repository—is encountered."
11932 #: ../source/book.xml:16956
11937 #: ../source/book.xml:16959
11938 msgid "Causes Subversion to use strict semantics, a notion which is rather vague unless talking about specific subcommands (namely, <command>svn propget</command>)."
11942 #: ../source/book.xml:16966
11947 #: ../source/book.xml:16967
11952 #: ../source/book.xml:16970
11953 msgid "Tells Subversion to get the list of files that you wish to operate on from the filename you provide instead of listing all the files on the command line."
11957 #: ../source/book.xml:16978 ../source/book.xml:22717
11962 #: ../source/book.xml:16979 ../source/book.xml:22718
11967 #: ../source/book.xml:16982 ../source/book.xml:22721
11968 msgid "Indicates that you are providing your username for authentication on the command line—otherwise, if it is needed, Subversion will prompt you for it."
11972 #: ../source/book.xml:16989
11973 msgid "<option>--verbose</option> (<option>-v</option>)"
11977 #: ../source/book.xml:16991
11978 msgid "Requests that the client print out as much information as it can while running any subcommand. This may result in Subversion printing out additional fields, detailed information about every file, or additional information regarding its actions."
11982 #: ../source/book.xml:17000 ../source/book.xml:23037 ../source/book.xml:23184
11987 #: ../source/book.xml:17003
11988 msgid "Prints the client version info. This information not only includes the version number of the client, but also a listing of all repository access modules that the client can use to access a Subversion repository. With <option>--quiet</option> (<option>-q</option>) it prints only the version number in a compact form."
11992 #: ../source/book.xml:17014
11997 #: ../source/book.xml:17017
11998 msgid "Prints output in XML format."
12002 #: ../source/book.xml:17025
12003 msgid "<command>svn</command> Subcommands"
12007 #: ../source/book.xml:17027 ../source/book.xml:22734
12008 msgid "Here are the various subcommands:"
12012 #: ../source/book.xml:17031 ../source/book.xml:17134 ../source/book.xml:17238 ../source/book.xml:17323 ../source/book.xml:17454 ../source/book.xml:17530 ../source/book.xml:17658 ../source/book.xml:17814 ../source/book.xml:17924 ../source/book.xml:18177 ../source/book.xml:18289 ../source/book.xml:18342 ../source/book.xml:18446 ../source/book.xml:18647 ../source/book.xml:18765 ../source/book.xml:18859 ../source/book.xml:19083 ../source/book.xml:19205 ../source/book.xml:19290 ../source/book.xml:19397 ../source/book.xml:19476 ../source/book.xml:19555 ../source/book.xml:19636 ../source/book.xml:19724 ../source/book.xml:19849 ../source/book.xml:19938 ../source/book.xml:20044 ../source/book.xml:20389 ../source/book.xml:20551 ../source/book.xml:20638 ../source/book.xml:20932 ../source/book.xml:20991 ../source/book.xml:21030 ../source/book.xml:21133 ../source/book.xml:21166 ../source/book.xml:21212 ../source/book.xml:21244 ../source/book.xml:21290 ../source/book.xml:21353 ../source/book.xml:21399 ../source/book.xml:21437 ../source/book.xml:21514 ../source/book.xml:21558 ../source/book.xml:21606 ../source/book.xml:21663 ../source/book.xml:21810 ../source/book.xml:21854 ../source/book.xml:21909 ../source/book.xml:21999 ../source/book.xml:22043 ../source/book.xml:22112 ../source/book.xml:22157 ../source/book.xml:22189 ../source/book.xml:22252 ../source/book.xml:22300 ../source/book.xml:22349 ../source/book.xml:22393 ../source/book.xml:22446 ../source/book.xml:22508 ../source/book.xml:22561 ../source/book.xml:22599 ../source/book.xml:22738 ../source/book.xml:22804 ../source/book.xml:22875
12013 msgid "subcommands"
12017 #: ../source/book.xml:17032
12022 #: ../source/book.xml:17036
12023 msgid "Add files, directories, or symbolic links."
12027 #: ../source/book.xml:17040 ../source/book.xml:17144 ../source/book.xml:17248 ../source/book.xml:17332 ../source/book.xml:17463 ../source/book.xml:17539 ../source/book.xml:17668 ../source/book.xml:17824 ../source/book.xml:17933 ../source/book.xml:18186 ../source/book.xml:18298 ../source/book.xml:18352 ../source/book.xml:18456 ../source/book.xml:18656 ../source/book.xml:18776 ../source/book.xml:18868 ../source/book.xml:19093 ../source/book.xml:19214 ../source/book.xml:19299 ../source/book.xml:19406 ../source/book.xml:19486 ../source/book.xml:19564 ../source/book.xml:19645 ../source/book.xml:19733 ../source/book.xml:19859 ../source/book.xml:19947 ../source/book.xml:20053 ../source/book.xml:20398 ../source/book.xml:20560 ../source/book.xml:20647 ../source/book.xml:20941 ../source/book.xml:21000 ../source/book.xml:21039 ../source/book.xml:21142 ../source/book.xml:21175 ../source/book.xml:21224 ../source/book.xml:21255 ../source/book.xml:21301 ../source/book.xml:21362 ../source/book.xml:21408 ../source/book.xml:21450 ../source/book.xml:21524 ../source/book.xml:21567 ../source/book.xml:21615 ../source/book.xml:21672 ../source/book.xml:21819 ../source/book.xml:21863 ../source/book.xml:21918 ../source/book.xml:22008 ../source/book.xml:22052 ../source/book.xml:22121 ../source/book.xml:22166 ../source/book.xml:22200 ../source/book.xml:22262 ../source/book.xml:22310 ../source/book.xml:22359 ../source/book.xml:22403 ../source/book.xml:22456 ../source/book.xml:22517 ../source/book.xml:22571 ../source/book.xml:22608 ../source/book.xml:22749 ../source/book.xml:22814 ../source/book.xml:22885 ../source/book.xml:23129
12032 #: ../source/book.xml:17042
12034 msgid "svn add PATH..."
12038 #: ../source/book.xml:17046 ../source/book.xml:17150 ../source/book.xml:17254 ../source/book.xml:17338 ../source/book.xml:17469 ../source/book.xml:17545 ../source/book.xml:17674 ../source/book.xml:17831 ../source/book.xml:17941 ../source/book.xml:18193 ../source/book.xml:18304 ../source/book.xml:18358 ../source/book.xml:18462 ../source/book.xml:18662 ../source/book.xml:18782 ../source/book.xml:18876 ../source/book.xml:19101 ../source/book.xml:19221 ../source/book.xml:19305 ../source/book.xml:19413 ../source/book.xml:19493 ../source/book.xml:19571 ../source/book.xml:19652 ../source/book.xml:19740 ../source/book.xml:19865 ../source/book.xml:19953 ../source/book.xml:20059 ../source/book.xml:20405 ../source/book.xml:20566 ../source/book.xml:20653 ../source/book.xml:20947 ../source/book.xml:21006 ../source/book.xml:21045 ../source/book.xml:21148 ../source/book.xml:21181 ../source/book.xml:21230 ../source/book.xml:21261 ../source/book.xml:21307 ../source/book.xml:21368 ../source/book.xml:21414 ../source/book.xml:21456 ../source/book.xml:21530 ../source/book.xml:21573 ../source/book.xml:21621 ../source/book.xml:21678 ../source/book.xml:21825 ../source/book.xml:21869 ../source/book.xml:21924 ../source/book.xml:22014 ../source/book.xml:22058 ../source/book.xml:22127 ../source/book.xml:22172 ../source/book.xml:22206 ../source/book.xml:22268 ../source/book.xml:22316 ../source/book.xml:22365 ../source/book.xml:22409 ../source/book.xml:22462 ../source/book.xml:22523 ../source/book.xml:22577 ../source/book.xml:22614 ../source/book.xml:22755 ../source/book.xml:22820 ../source/book.xml:22891 ../source/book.xml:23135 ../source/book.xml:23265 ../source/book.xml:23564 ../source/book.xml:23611 ../source/book.xml:23660 ../source/book.xml:23707 ../source/book.xml:23770 ../source/book.xml:23831 ../source/book.xml:23882 ../source/book.xml:23928 ../source/book.xml:23981 ../source/book.xml:24994
12039 msgid "Description"
12043 #: ../source/book.xml:17048
12044 msgid "Schedule files, directories, or symbolic links in your working copy for addition to the repository. They will be uploaded and added to the repository on your next commit. If you add something and change your mind before committing, you can unschedule the addition using <command>svn revert</command>."
12048 #: ../source/book.xml:17058 ../source/book.xml:17159 ../source/book.xml:17262 ../source/book.xml:17350 ../source/book.xml:17487 ../source/book.xml:17570 ../source/book.xml:17716 ../source/book.xml:17846 ../source/book.xml:18047 ../source/book.xml:18212 ../source/book.xml:18311 ../source/book.xml:18370 ../source/book.xml:18548 ../source/book.xml:18703 ../source/book.xml:18793 ../source/book.xml:18905 ../source/book.xml:19135 ../source/book.xml:19235 ../source/book.xml:19338 ../source/book.xml:19424 ../source/book.xml:19504 ../source/book.xml:19582 ../source/book.xml:19663 ../source/book.xml:19758 ../source/book.xml:19878 ../source/book.xml:19966 ../source/book.xml:20302 ../source/book.xml:20425 ../source/book.xml:20578 ../source/book.xml:20705 ../source/book.xml:21158 ../source/book.xml:22181 ../source/book.xml:22416 ../source/book.xml:22469 ../source/book.xml:22773 ../source/book.xml:22834 ../source/book.xml:22904
12049 msgid "Alternate Names"
12053 #: ../source/book.xml:17060 ../source/book.xml:17264 ../source/book.xml:17489 ../source/book.xml:18214 ../source/book.xml:18372 ../source/book.xml:18550 ../source/book.xml:18795 ../source/book.xml:18907 ../source/book.xml:19137 ../source/book.xml:19237 ../source/book.xml:19880 ../source/book.xml:19968 ../source/book.xml:20580 ../source/book.xml:21376 ../source/book.xml:21538 ../source/book.xml:22327 ../source/book.xml:22775
12058 #: ../source/book.xml:17064 ../source/book.xml:17165 ../source/book.xml:17268 ../source/book.xml:17356 ../source/book.xml:17493 ../source/book.xml:17578 ../source/book.xml:17722 ../source/book.xml:17852 ../source/book.xml:18053 ../source/book.xml:18218 ../source/book.xml:18320 ../source/book.xml:18376 ../source/book.xml:18554 ../source/book.xml:18709 ../source/book.xml:18799 ../source/book.xml:18911 ../source/book.xml:19141 ../source/book.xml:19241 ../source/book.xml:19344 ../source/book.xml:19430 ../source/book.xml:19510 ../source/book.xml:19588 ../source/book.xml:19669 ../source/book.xml:19764 ../source/book.xml:19884 ../source/book.xml:19972 ../source/book.xml:20308 ../source/book.xml:20431 ../source/book.xml:20584 ../source/book.xml:20711
12063 #: ../source/book.xml:17066
12064 msgid "Working Copy"
12068 #: ../source/book.xml:17070 ../source/book.xml:17171 ../source/book.xml:17274 ../source/book.xml:17362 ../source/book.xml:17499 ../source/book.xml:17584 ../source/book.xml:17729 ../source/book.xml:17859 ../source/book.xml:18059 ../source/book.xml:18224 ../source/book.xml:18326 ../source/book.xml:18382 ../source/book.xml:18560 ../source/book.xml:18715 ../source/book.xml:18805 ../source/book.xml:18917 ../source/book.xml:19147 ../source/book.xml:19247 ../source/book.xml:19350 ../source/book.xml:19436 ../source/book.xml:19516 ../source/book.xml:19594 ../source/book.xml:19675 ../source/book.xml:19770 ../source/book.xml:19890 ../source/book.xml:19978 ../source/book.xml:20314 ../source/book.xml:20437 ../source/book.xml:20590 ../source/book.xml:20717
12069 msgid "Accesses Repository"
12073 #: ../source/book.xml:17072 ../source/book.xml:17501 ../source/book.xml:18328 ../source/book.xml:19892 ../source/book.xml:19980
12078 #: ../source/book.xml:17076 ../source/book.xml:17177 ../source/book.xml:17280 ../source/book.xml:17368 ../source/book.xml:17505 ../source/book.xml:17590 ../source/book.xml:17736 ../source/book.xml:17865 ../source/book.xml:18066 ../source/book.xml:18230 ../source/book.xml:18332 ../source/book.xml:18388 ../source/book.xml:18566 ../source/book.xml:18721 ../source/book.xml:18811 ../source/book.xml:18923 ../source/book.xml:19153 ../source/book.xml:19253 ../source/book.xml:19356 ../source/book.xml:19442 ../source/book.xml:19522 ../source/book.xml:19600 ../source/book.xml:19681 ../source/book.xml:19776 ../source/book.xml:19896 ../source/book.xml:19984 ../source/book.xml:20320 ../source/book.xml:20443 ../source/book.xml:20596 ../source/book.xml:20723 ../source/book.xml:20961 ../source/book.xml:21019 ../source/book.xml:21094 ../source/book.xml:21195 ../source/book.xml:21315 ../source/book.xml:21374 ../source/book.xml:21463 ../source/book.xml:21536 ../source/book.xml:21580 ../source/book.xml:21640 ../source/book.xml:21832 ../source/book.xml:21875 ../source/book.xml:21968 ../source/book.xml:22021 ../source/book.xml:22065 ../source/book.xml:22135 ../source/book.xml:22214 ../source/book.xml:22275 ../source/book.xml:22325 ../source/book.xml:22371 ../source/book.xml:22422 ../source/book.xml:22475 ../source/book.xml:22532 ../source/book.xml:22779 ../source/book.xml:22840 ../source/book.xml:22910 ../source/book.xml:23157
12083 #: ../source/book.xml:17078
12085 msgid "\n--targets FILENAME\n--non-recursive (-N)\n--quiet (-q)\n--config-dir DIR\n--no-ignore\n--auto-props\n--no-auto-props\n--force\n"
12089 #: ../source/book.xml:17091 ../source/book.xml:17217 ../source/book.xml:17293 ../source/book.xml:17384 ../source/book.xml:17514 ../source/book.xml:17610 ../source/book.xml:17755 ../source/book.xml:17885 ../source/book.xml:18090 ../source/book.xml:18248 ../source/book.xml:18410 ../source/book.xml:18583 ../source/book.xml:18738 ../source/book.xml:18829 ../source/book.xml:18943 ../source/book.xml:19174 ../source/book.xml:19271 ../source/book.xml:19376 ../source/book.xml:19458 ../source/book.xml:19538 ../source/book.xml:19616 ../source/book.xml:19698 ../source/book.xml:19796 ../source/book.xml:19907 ../source/book.xml:19995 ../source/book.xml:20338 ../source/book.xml:20460 ../source/book.xml:20610 ../source/book.xml:20742 ../source/book.xml:20972 ../source/book.xml:21105 ../source/book.xml:21273 ../source/book.xml:21423 ../source/book.xml:21471 ../source/book.xml:21588 ../source/book.xml:21649 ../source/book.xml:21694 ../source/book.xml:21841 ../source/book.xml:21884 ../source/book.xml:21977 ../source/book.xml:22030 ../source/book.xml:22076 ../source/book.xml:22144 ../source/book.xml:22223 ../source/book.xml:22284 ../source/book.xml:22331 ../source/book.xml:22380 ../source/book.xml:22432 ../source/book.xml:22486 ../source/book.xml:22542 ../source/book.xml:22588 ../source/book.xml:22620 ../source/book.xml:22791 ../source/book.xml:22852 ../source/book.xml:22922 ../source/book.xml:23195
12094 #: ../source/book.xml:17093
12095 msgid "To add a file to your working copy:"
12099 #: ../source/book.xml:17094
12101 msgid "\n$ svn add foo.c \nA foo.c\n"
12105 #: ../source/book.xml:17098
12106 msgid "When adding a directory, the default behavior of <command>svn add</command> is to recurse:"
12110 #: ../source/book.xml:17100
12112 msgid "\n$ svn add testdir\nA testdir\nA testdir/a\nA testdir/b\nA testdir/c\nA testdir/d\n"
12116 #: ../source/book.xml:17108
12117 msgid "You can add a directory without adding its contents:"
12121 #: ../source/book.xml:17110
12123 msgid "\n$ svn add --non-recursive otherdir\nA otherdir\n"
12127 #: ../source/book.xml:17114
12128 msgid "Normally, the command <command>svn add *</command> will skip over any directories that are already under version control. Sometimes, however, you may want to add every unversioned object in your working copy, including those hiding deeper down. Passing the <option>--force</option> option makes <command>svn add</command> recurse into versioned directories:"
12132 #: ../source/book.xml:17122
12134 msgid "\n$ svn add * --force\nA foo.c\nA somedir/bar.c\nA otherdir/docs/baz.doc\n…\n"
12138 #: ../source/book.xml:17135
12143 #: ../source/book.xml:17138
12148 #: ../source/book.xml:17139
12149 msgid "Show author and revision information in-line for the specified files or URLs."
12153 #: ../source/book.xml:17146
12155 msgid "svn blame TARGET[@REV]..."
12159 #: ../source/book.xml:17152
12160 msgid "Show author and revision information in-line for the specified files or URLs. Each line of text is annotated at the beginning with the author (username) and the revision number for the last change to that line."
12164 #: ../source/book.xml:17161
12165 msgid "praise, annotate, ann"
12169 #: ../source/book.xml:17167 ../source/book.xml:17270 ../source/book.xml:18055 ../source/book.xml:18322 ../source/book.xml:18556 ../source/book.xml:18711 ../source/book.xml:18913 ../source/book.xml:20310
12174 #: ../source/book.xml:17173 ../source/book.xml:17276 ../source/book.xml:17364 ../source/book.xml:17586 ../source/book.xml:18384 ../source/book.xml:18717 ../source/book.xml:18807 ../source/book.xml:18919 ../source/book.xml:20439 ../source/book.xml:20592 ../source/book.xml:20719
12179 #: ../source/book.xml:17179
12181 msgid "\n--revision (-r) ARG\n--verbose (-v)\n--incremental\n--xml\n--extensions (-x) ARG\n--force\n--username ARG\n--password ARG\n--no-auth-cache\n--non-interactive\n--config-dir ARG\n"
12185 #: ../source/book.xml:17219
12186 msgid "If you want to see blame annotated source for <filename>readme.txt</filename> in your test repository:"
12190 #: ../source/book.xml:17222
12192 msgid "\n$ svn blame http://svn.red-bean.com/repos/test/readme.txt\n 3 sally This is a README file.\n 5 harry You should read this.\n"
12196 #: ../source/book.xml:17227
12197 msgid "Even if <command>svn blame</command> says that Harry last modified readme.txt in revision 5, you'll have to examine exactly what the revision changed to be sure that Harry changed the <emphasis>context</emphasis> of the line—he may have just adjusted the whitespace."
12201 #: ../source/book.xml:17239 ../source/book.xml:21855
12206 #: ../source/book.xml:17243
12207 msgid "Output the contents of the specified files or URLs."
12211 #: ../source/book.xml:17250
12213 msgid "svn cat TARGET[@REV]..."
12217 #: ../source/book.xml:17256
12218 msgid "Output the contents of the specified files or URLs. For listing the contents of directories, see <command>svn list</command>."
12222 #: ../source/book.xml:17282
12224 msgid "\n--revision (-r) REV\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
12228 #: ../source/book.xml:17295
12229 msgid "If you want to view readme.txt in your repository without checking it out:"
12233 #: ../source/book.xml:17297
12235 msgid "\n$ svn cat http://svn.red-bean.com/repos/test/readme.txt\nThis is a README file.\nYou should read this.\n"
12239 #: ../source/book.xml:17303
12240 msgid "If your working copy is out of date (or you have local modifications) and you want to see the <literal>HEAD</literal> revision of a file in your working copy, <command>svn cat -r HEAD</command> will automatically fetch the <literal>HEAD</literal> revision when you give it a path:"
12244 #: ../source/book.xml:17310
12246 msgid "\n$ cat foo.c\nThis file is in my local working copy \nand has changes that I've made.\n\n$ svn cat -r HEAD foo.c\nLatest revision fresh from the repository!\n"
12250 #: ../source/book.xml:17324
12255 #: ../source/book.xml:17327
12256 msgid "svn checkout"
12260 #: ../source/book.xml:17328
12261 msgid "Check out a working copy from a repository."
12265 #: ../source/book.xml:17334
12267 msgid "svn checkout URL[@REV]... [PATH]"
12271 #: ../source/book.xml:17340
12272 msgid "Check out a working copy from a repository. If <replaceable>PATH</replaceable> is omitted, the basename of the URL will be used as the destination. If multiple URLs are given each will be checked out into a subdirectory of <replaceable>PATH</replaceable>, with the name of the subdirectory being the basename of the URL."
12276 #: ../source/book.xml:17352
12281 #: ../source/book.xml:17358
12282 msgid "Creates a working copy."
12286 #: ../source/book.xml:17370
12288 msgid "\n--revision (-r) REV\n--quiet (-q)\n--non-recursive (-N)\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--ignore-externals\n--config-dir DIR\n"
12292 #: ../source/book.xml:17386
12293 msgid "Check out a working copy into a directory called <filename>mine</filename>:"
12297 #: ../source/book.xml:17388
12299 msgid "\n$ svn checkout file:///tmp/repos/test mine\nA mine/a\nA mine/b\nChecked out revision 2.\n$ ls\nmine\n"
12303 #: ../source/book.xml:17396
12304 msgid "Check out two different directories into two separate working copies:"
12308 #: ../source/book.xml:17398
12310 msgid "\n$ svn checkout file:///tmp/repos/test file:///tmp/repos/quiz\nA test/a\nA test/b\nChecked out revision 2.\nA quiz/l\nA quiz/m\nChecked out revision 2.\n$ ls\nquiz test\n"
12314 #: ../source/book.xml:17409
12315 msgid "Check out two different directories into two separate working copies, but place both into a directory called <filename>working-copies</filename>:"
12319 #: ../source/book.xml:17412
12321 msgid "\n$ svn checkout file:///tmp/repos/test file:///tmp/repos/quiz working-copies\nA working-copies/test/a\nA working-copies/test/b\nChecked out revision 2.\nA working-copies/quiz/l\nA working-copies/quiz/m\nChecked out revision 2.\n$ ls\nworking-copies\n"
12325 #: ../source/book.xml:17423
12326 msgid "If you interrupt a checkout (or something else interrupts your checkout, like loss of connectivity, etc.), you can restart it either by issuing the identical checkout command again, or by updating the incomplete working copy:"
12330 #: ../source/book.xml:17428
12332 msgid "\n$ svn checkout file:///tmp/repos/test test\nA test/a\nA test/b\n^C\nsvn: The operation was interrupted\nsvn: caught SIGINT\n\n$ svn checkout file:///tmp/repos/test test\nA test/c\nA test/d\n^C\nsvn: The operation was interrupted\nsvn: caught SIGINT\n\n$ cd test\n$ svn update\nA test/e\nA test/f\nUpdated to revision 3.\n"
12336 #: ../source/book.xml:17455
12341 #: ../source/book.xml:17458
12342 msgid "svn cleanup"
12346 #: ../source/book.xml:17459
12347 msgid "Recursively clean up the working copy."
12351 #: ../source/book.xml:17465
12353 msgid "svn cleanup [PATH...]"
12357 #: ../source/book.xml:17471
12358 msgid "Recursively clean up the working copy, removing working copy locks and resuming unfinished operations. If you ever get a <quote>working copy locked</quote> error, run this command to remove stale locks and get your working copy into a usable state again."
12362 #: ../source/book.xml:17476
12363 msgid "If, for some reason, an <command>svn update</command> fails due to a problem running an external diff program (e.g. user input or network failure), pass the <option>--diff3-cmd</option> to allow cleanup to complete any merging with your external diff program. You can also specify any configuration directory with the <option>--config-dir</option> option, but you should need these options extremely infrequently."
12367 #: ../source/book.xml:17495 ../source/book.xml:19143 ../source/book.xml:19886 ../source/book.xml:19974 ../source/book.xml:20433 ../source/book.xml:20713
12368 msgid "Working copy"
12372 #: ../source/book.xml:17507
12374 msgid "\n--diff3-cmd CMD\n--config-dir DIR\n"
12378 #: ../source/book.xml:17516
12379 msgid "Well, there's not much to the examples here as <command>svn cleanup</command> generates no output. If you pass no <replaceable>PATH</replaceable>, <quote><filename>.</filename></quote> is used."
12383 #: ../source/book.xml:17520
12385 msgid "\n$ svn cleanup\n\n$ svn cleanup /path/to/working-copy\n"
12389 #: ../source/book.xml:17531
12394 #: ../source/book.xml:17535
12395 msgid "Send changes from your working copy to the repository."
12399 #: ../source/book.xml:17541
12401 msgid "svn commit [PATH...]"
12405 #: ../source/book.xml:17547
12406 msgid "Send changes from your working copy to the repository. If you do not supply a log message with your commit by using either the <option>--file</option> or <option>--message</option> option, <command>svn</command> will launch your editor for you to compose a commit message. See the <literal>editor-cmd</literal> section in <xref linkend=\"svn.advanced.confarea.opts.config\"/>."
12410 #: ../source/book.xml:17554
12411 msgid "<command>svn commit</command> will send any lock tokens that it finds and will release locks on all <replaceable>PATHS</replaceable> committed (recursively), unless <option>--no-unlock</option> is passed."
12415 #: ../source/book.xml:17559
12416 msgid "If you begin a commit and Subversion launches your editor to compose the commit message, you can still abort without committing your changes. If you want to cancel your commit, just quit your editor without saving your commit message and Subversion will prompt you to either abort the commit, continue with no message, or edit the message again."
12420 #: ../source/book.xml:17572
12421 msgid "ci (short for <quote>check in</quote>; not <quote>co</quote>, which is short for <quote>checkout</quote>)"
12425 #: ../source/book.xml:17580
12426 msgid "Working copy, repository"
12430 #: ../source/book.xml:17592
12432 msgid "\n--message (-m) TEXT\n--file (-F) FILE\n--quiet (-q)\n--no-unlock\n--non-recursive (-N)\n--targets FILENAME\n--force-log\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--encoding ENC\n--config-dir DIR\n"
12436 #: ../source/book.xml:17612
12437 msgid "Commit a simple modification to a file with the commit message on the command line and an implicit target of your current directory (<quote><filename>.</filename></quote>):"
12441 #: ../source/book.xml:17616
12443 msgid "\n$ svn commit -m \"added howto section.\"\nSending a\nTransmitting file data .\nCommitted revision 3.\n"
12447 #: ../source/book.xml:17622
12448 msgid "Commit a modification to the file <filename>foo.c</filename> (explicitly specified on the command line) with the commit message in a file named <literal>msg</literal>:"
12452 #: ../source/book.xml:17626
12454 msgid "\n$ svn commit -F msg foo.c\nSending foo.c\nTransmitting file data .\nCommitted revision 5.\n"
12458 #: ../source/book.xml:17632
12459 msgid "If you want to use a file that's under version control for your commit message with <option>--file</option>, you need to pass the <option>--force-log</option> option:"
12463 #: ../source/book.xml:17636
12465 msgid "\n$ svn commit --file file_under_vc.txt foo.c\nsvn: The log message file is under version control\nsvn: Log message file is a versioned file; use '--force-log' to override\n\n$ svn commit --force-log --file file_under_vc.txt foo.c\nSending foo.c\nTransmitting file data .\nCommitted revision 6.\n"
12469 #: ../source/book.xml:17646
12470 msgid "To commit a file scheduled for deletion:"
12474 #: ../source/book.xml:17647
12476 msgid "\n$ svn commit -m \"removed file 'c'.\"\nDeleting c\n\nCommitted revision 7.\n"
12480 #: ../source/book.xml:17659
12485 #: ../source/book.xml:17663
12486 msgid "Copy a file or directory in a working copy or in the repository."
12490 #: ../source/book.xml:17670
12492 msgid "svn copy SRC DST"
12496 #: ../source/book.xml:17676
12497 msgid "Copy a file in a working copy or in the repository. <replaceable>SRC</replaceable> and <replaceable>DST</replaceable> can each be either a working copy (WC) path or URL:"
12501 #: ../source/book.xml:17682 ../source/book.xml:19322
12502 msgid "WC -> WC"
12506 #: ../source/book.xml:17684
12507 msgid "Copy and schedule an item for addition (with history)."
12511 #: ../source/book.xml:17689
12512 msgid "WC -> URL"
12516 #: ../source/book.xml:17691
12517 msgid "Immediately commit a copy of WC to URL."
12521 #: ../source/book.xml:17695
12522 msgid "URL -> WC"
12526 #: ../source/book.xml:17697
12527 msgid "Check out URL into WC, and schedule it for addition."
12531 #: ../source/book.xml:17702 ../source/book.xml:19329
12532 msgid "URL -> URL"
12536 #: ../source/book.xml:17704
12537 msgid "Complete server-side copy. This is usually used to branch and tag."
12541 #: ../source/book.xml:17710
12542 msgid "You can only copy files within a single repository. Subversion does not support cross-repository copying."
12546 #: ../source/book.xml:17718
12551 #: ../source/book.xml:17724
12552 msgid "Repository if destination is a URL."
12556 #: ../source/book.xml:17725
12557 msgid "Working copy if destination is a WC path."
12561 #: ../source/book.xml:17731
12562 msgid "If source or destination is in the repository, or if needed to look up the source revision number."
12566 #: ../source/book.xml:17738
12568 msgid "\n--message (-m) TEXT\n--file (-F) FILE\n--revision (-r) REV\n--quiet (-q)\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--force-log\n--editor-cmd EDITOR\n--encoding ENC\n--config-dir DIR\n"
12572 #: ../source/book.xml:17757
12573 msgid "Copy an item within your working copy (just schedules the copy—nothing goes into the repository until you commit):"
12577 #: ../source/book.xml:17760
12579 msgid "\n$ svn copy foo.txt bar.txt\nA bar.txt\n$ svn status\nA + bar.txt\n"
12583 #: ../source/book.xml:17766
12584 msgid "Copy an item in your working copy to a URL in the repository (an immediate commit, so you must supply a commit message):"
12588 #: ../source/book.xml:17769
12590 msgid "\n$ svn copy near.txt file:///tmp/repos/test/far-away.txt -m \"Remote copy.\"\n\nCommitted revision 8.\n"
12594 #: ../source/book.xml:17774
12595 msgid "Copy an item from the repository to your working copy (just schedules the copy—nothing goes into the repository until you commit):"
12599 #: ../source/book.xml:17778
12600 msgid "This is the recommended way to resurrect a dead file in your repository!"
12604 #: ../source/book.xml:17781
12606 msgid "\n$ svn copy file:///tmp/repos/test/far-away near-here\nA near-here\n"
12610 #: ../source/book.xml:17785
12611 msgid "And finally, copying between two URLs:"
12615 #: ../source/book.xml:17786
12617 msgid "\n$ svn copy file:///tmp/repos/test/far-away file:///tmp/repos/test/over-there -m \"remote copy.\"\n\nCommitted revision 9.\n"
12621 #: ../source/book.xml:17792
12622 msgid "This is the easiest way to <quote>tag</quote> a revision in your repository—just <command>svn copy</command> that revision (usually <literal>HEAD</literal>) into your tags directory."
12626 #: ../source/book.xml:17797
12628 msgid "\n$ svn copy file:///tmp/repos/test/trunk file:///tmp/repos/test/tags/0.6.32-prerelease -m \"tag tree\"\n\nCommitted revision 12.\n"
12632 #: ../source/book.xml:17802
12633 msgid "And don't worry if you forgot to tag—you can always specify an older revision and tag anytime:"
12637 #: ../source/book.xml:17804
12639 msgid "\n$ svn copy -r 11 file:///tmp/repos/test/trunk file:///tmp/repos/test/tags/0.6.32-prerelease -m \"Forgot to tag at rev 11\"\n\nCommitted revision 13.\n"
12643 #: ../source/book.xml:17815
12648 #: ../source/book.xml:17819
12649 msgid "Delete an item from a working copy or the repository."
12653 #: ../source/book.xml:17826
12655 msgid "svn delete PATH..."
12659 #: ../source/book.xml:17827
12661 msgid "svn delete URL..."
12665 #: ../source/book.xml:17833
12666 msgid "Items specified by <replaceable>PATH</replaceable> 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 <option>--force</option> option to override this behavior."
12670 #: ../source/book.xml:17840
12671 msgid "Items specified by URL are deleted from the repository via an immediate commit. Multiple URLs are committed atomically."
12675 #: ../source/book.xml:17848
12676 msgid "del, remove, rm"
12680 #: ../source/book.xml:17854
12681 msgid "Working copy if operating on files, repository if operating on URLs"
12685 #: ../source/book.xml:17861 ../source/book.xml:18562
12686 msgid "Only if operating on URLs"
12690 #: ../source/book.xml:17867
12692 msgid "\n--force\n--force-log\n--message (-m) TEXT\n--file (-F) FILE\n--quiet (-q)\n--targets FILENAME\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--editor-cmd EDITOR\n--encoding ENC\n--config-dir DIR\n"
12696 #: ../source/book.xml:17887
12697 msgid "Using <command>svn</command> to delete a file from your working copy deletes your local copy of the file, but merely schedules it to be deleted from the repository. When you commit, the file is deleted in the repository."
12701 #: ../source/book.xml:17892
12703 msgid "\n$ svn delete myfile\nD myfile\n\n$ svn commit -m \"Deleted file 'myfile'.\"\nDeleting myfile\nTransmitting file data .\nCommitted revision 14.\n"
12707 #: ../source/book.xml:17901
12708 msgid "Deleting a URL, however, is immediate, so you have to supply a log message:"
12712 #: ../source/book.xml:17903
12714 msgid "\n$ svn delete -m \"Deleting file 'yourfile'\" file:///tmp/repos/test/yourfile\n\nCommitted revision 15.\n"
12718 #: ../source/book.xml:17908
12719 msgid "Here's an example of how to force deletion of a file that has local mods:"
12723 #: ../source/book.xml:17910
12725 msgid "\n$ svn delete over-there \nsvn: Attempting restricted operation for modified resource\nsvn: Use --force to override this restriction\nsvn: 'over-there' has local modifications\n\n$ svn delete --force over-there \nD over-there\n"
12729 #: ../source/book.xml:17925 ../source/book.xml:22044
12734 #: ../source/book.xml:17929
12735 msgid "Display the differences between two revisions or paths."
12739 #: ../source/book.xml:17935
12741 msgid "diff [-c M | -r N[:M]] [TARGET[@REV]...]"
12745 #: ../source/book.xml:17936
12747 msgid "diff [-r N[:M]] --old=OLD-TGT[@OLDREV] [--new=NEW-TGT[@NEWREV]] [PATH...]"
12751 #: ../source/book.xml:17937
12753 msgid "diff OLD-URL[@OLDREV] NEW-URL[@NEWREV]"
12757 #: ../source/book.xml:17943
12758 msgid "Display the differences between two paths. The ways you can use <command>svn diff</command> are:"
12762 #: ../source/book.xml:17945
12763 msgid "Use just <command>svn diff'</command>to display local modifications in a working copy."
12767 #: ../source/book.xml:17947
12768 msgid "Display the changes made to <replaceable>TARGET</replaceable>s as they are seen in <replaceable>REV</replaceable> between two revisions. <replaceable>TARGET</replaceable>s may be all working copy paths or all <replaceable>URL</replaceable>s. If <replaceable>TARGET</replaceable>s are working copy paths, <replaceable>N</replaceable> defaults to <literal>BASE</literal> and <replaceable>M</replaceable> to the working copy; if <replaceable>URL</replaceable>s, <replaceable>N</replaceable> must be specified and <replaceable>M</replaceable> defaults to <literal>HEAD</literal>. The <quote>-c M</quote> option is equivalent to <quote>-r N:M</quote> where <literal>N = M-1</literal>. Using <quote>-c -M</quote> does the reverse: <quote>-r M:N</quote> where <literal>N = M-1</literal>."
12772 #: ../source/book.xml:17963
12773 msgid "Display the differences between <replaceable>OLD-TGT</replaceable> as it was seen in <replaceable>OLDREV</replaceable> and <replaceable>NEW-TGT</replaceable> as it was seen ain <replaceable>NEWREV</replaceable>. <replaceable>PATH</replaceable>s, if given, are relative to <replaceable>OLD-TGT</replaceable> and <replaceable>NEW-TGT</replaceable> and restrict the output to differences for those paths. <replaceable>OLD-TGT</replaceable> and <replaceable>NEW-TGT</replaceable> may be working copy paths or <replaceable>URL[@REV]</replaceable>. <replaceable>NEW-TGT</replaceable> defaults to <replaceable>OLD-TGT</replaceable> if not specified. <quote>-r N</quote> makes OLDREV default to N, -r N:M makes <replaceable>OLDREV</replaceable> default to <replaceable>N</replaceable> and <replaceable>NEWREV</replaceable> default to <replaceable>M</replaceable>."
12777 #: ../source/book.xml:17982
12778 msgid "Shorthand for <command>svn diff --old=OLD-URL[@OLDREV] --new=NEW-URL[@NEWREV]</command>"
12782 #: ../source/book.xml:17984
12783 msgid "<command>svn diff -r N:M URL</command> is shorthand for <command>svn diff -r N:M --old=URL --new=URL</command>."
12787 #: ../source/book.xml:17987
12788 msgid "<command>svn diff [-r N[:M]] URL1[@N] URL2[@M]</command> is shorthand for <command>svn diff [-r N[:M]] --old=URL1 --new=URL2</command>."
12792 #: ../source/book.xml:17990
12793 msgid "If <replaceable>TARGET</replaceable> is a URL, then revs N and M can be given either via the <option>--revision</option> or by using <quote>@</quote> notation as described earlier."
12797 #: ../source/book.xml:17994
12798 msgid "If <replaceable>TARGET</replaceable> is a working copy path, then the <option>--revision</option> option means:"
12802 #: ../source/book.xml:18000
12803 msgid "--revision N:M"
12807 #: ../source/book.xml:18003
12808 msgid "The server compares <replaceable>TARGET</replaceable>@<replaceable>N</replaceable> and <replaceable>TARGET</replaceable>@<replaceable>M</replaceable>."
12812 #: ../source/book.xml:18011
12813 msgid "--revision N"
12817 #: ../source/book.xml:18014
12818 msgid "The client compares <replaceable>TARGET</replaceable>@<replaceable>N</replaceable> against working copy."
12822 #: ../source/book.xml:18020
12823 msgid "(no <option>--revision</option>)"
12827 #: ../source/book.xml:18022
12828 msgid "The client compares base and working copies of <replaceable>TARGET</replaceable>."
12832 #: ../source/book.xml:18027
12833 msgid "If the alternate syntax is used, the server compares <replaceable>URL1</replaceable> and <replaceable>URL2</replaceable> at revisions <replaceable>N</replaceable> and <replaceable>M</replaceable> respectively. If either <replaceable>N</replaceable> or <replaceable>M</replaceable> are omitted, a value of <literal>HEAD</literal> is assumed."
12837 #: ../source/book.xml:18035
12838 msgid "By default, <command>svn diff</command> ignores the ancestry of files and merely compares the contents of the two files being compared. If you use <option>--notice-ancestry</option>, the ancestry of the paths in question will be taken into consideration when comparing revisions (that is, if you run <command>svn diff</command> 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)."
12842 #: ../source/book.xml:18049
12847 #: ../source/book.xml:18061
12848 msgid "For obtaining differences against anything but <literal>BASE</literal> revision in your working copy"
12852 #: ../source/book.xml:18068
12854 msgid "\n--revision (-r) ARG\n--change (-c) ARG\n--old ARG\n--new ARG\n--non-recursive (-N)\n--diff-cmd CMD\n--extensions (-x) \"ARGS\"\n--no-diff-deleted\n--notice-ancestry\n--summarize\n--force\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n\n"
12858 #: ../source/book.xml:18092
12859 msgid "Compare <literal>BASE</literal> and your working copy (one of the most popular uses of <command>svn diff</command>):"
12863 #: ../source/book.xml:18095
12865 msgid "\n$ svn diff COMMITTERS \nIndex: COMMITTERS\n===================================================================\n--- COMMITTERS\t(revision 4404)\n+++ COMMITTERS\t(working copy)\n"
12869 #: ../source/book.xml:18102
12870 msgid "See what changed in the file <literal>COMMITTERS</literal> revision 9115:"
12874 #: ../source/book.xml:18104
12876 msgid "\n$ svn diff -c 9115 COMMITTERS \nIndex: COMMITTERS\n===================================================================\n--- COMMITTERS\t(revision 3900)\n+++ COMMITTERS\t(working copy)\n"
12880 #: ../source/book.xml:18111
12881 msgid "See how your working copy's modifications compare against an older revision:"
12885 #: ../source/book.xml:18113
12887 msgid "\n$ svn diff -r 3900 COMMITTERS \nIndex: COMMITTERS\n===================================================================\n--- COMMITTERS\t(revision 3900)\n+++ COMMITTERS\t(working copy)\n"
12891 #: ../source/book.xml:18120
12892 msgid "Compare revision 3000 to revision 3500 using <quote>@</quote> syntax:"
12896 #: ../source/book.xml:18122
12898 msgid "\n$ svn diff http://svn.collab.net/repos/svn/trunk/COMMITTERS@3000 http://svn.collab.net/repos/svn/trunk/COMMITTERS@3500\nIndex: COMMITTERS\n===================================================================\n--- COMMITTERS\t(revision 3000)\n+++ COMMITTERS\t(revision 3500)\n…\n"
12902 #: ../source/book.xml:18130
12903 msgid "Compare revision 3000 to revision 3500 using range notation (you only pass the one URL in this case):"
12907 #: ../source/book.xml:18133
12909 msgid "\n$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk/COMMITTERS\nIndex: COMMITTERS\n===================================================================\n--- COMMITTERS\t(revision 3000)\n+++ COMMITTERS\t(revision 3500)\n"
12913 #: ../source/book.xml:18140
12914 msgid "Compare revision 3000 to revision 3500 of all files in <filename>trunk</filename> using range notation:"
12918 #: ../source/book.xml:18142
12920 msgid "\n$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk\n "
12924 #: ../source/book.xml:18145
12925 msgid "Compare revision 3000 to revision 3500 of only three files in <filename>trunk</filename> using range notation:"
12929 #: ../source/book.xml:18148
12931 msgid "\n$ svn diff -r 3000:3500 --old http://svn.collab.net/repos/svn/trunk COMMITTERS README HACKING\n "
12935 #: ../source/book.xml:18151
12936 msgid "If you have a working copy, you can obtain the differences without typing in the long URLs:"
12940 #: ../source/book.xml:18153
12942 msgid "\n$ svn diff -r 3000:3500 COMMITTERS \nIndex: COMMITTERS\n===================================================================\n--- COMMITTERS\t(revision 3000)\n+++ COMMITTERS\t(revision 3500)\n"
12946 #: ../source/book.xml:18160
12947 msgid "Use <option>--diff-cmd</option><replaceable>CMD</replaceable><option>-x</option> to pass arguments directly to the external diff program"
12951 #: ../source/book.xml:18164
12953 msgid "\n$ svn diff --diff-cmd /usr/bin/diff -x \"-i -b\" COMMITTERS \nIndex: COMMITTERS\n===================================================================\n0a1,2\n> This is a test\n> \n"
12957 #: ../source/book.xml:18178
12962 #: ../source/book.xml:18181
12967 #: ../source/book.xml:18182
12968 msgid "Export a clean directory tree."
12972 #: ../source/book.xml:18188
12974 msgid "svn export [-r REV] URL[@PEGREV] [PATH]"
12978 #: ../source/book.xml:18189
12980 msgid "svn export [-r REV] PATH1[@PEGREV] [PATH2]"
12984 #: ../source/book.xml:18195
12985 msgid "The first form exports a clean directory tree from the repository specified by URL, at revision <replaceable>REV</replaceable> if it is given, otherwise at <literal>HEAD</literal>, into <replaceable>PATH</replaceable>. If <replaceable>PATH</replaceable> is omitted, the last component of the <replaceable>URL</replaceable> is used for the local directory name."
12989 #: ../source/book.xml:18203
12990 msgid "The second form exports a clean directory tree from the working copy specified by <replaceable>PATH1</replaceable> into <replaceable>PATH2</replaceable>. All local changes will be preserved, but files not under version control will not be copied."
12994 #: ../source/book.xml:18220
12999 #: ../source/book.xml:18226
13000 msgid "Only if exporting from a URL"
13004 #: ../source/book.xml:18232
13006 msgid "\n--revision (-r) REV\n--quiet (-q)\n--force\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--non-recursive (-N)\n--config-dir DIR\n--native-eol EOL\n--ignore-externals\n"
13010 #: ../source/book.xml:18250
13011 msgid "Export from your working copy (doesn't print every file and directory):"
13015 #: ../source/book.xml:18252
13017 msgid "\n$ svn export a-wc my-export\nExport complete.\n"
13021 #: ../source/book.xml:18256
13022 msgid "Export directly from the repository (prints every file and directory):"
13026 #: ../source/book.xml:18258
13028 msgid "\n$ svn export file:///tmp/repos my-export\nA my-export/test\nA my-export/quiz\n…\nExported revision 15.\n"
13032 #: ../source/book.xml:18265
13033 msgid "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 <option>--native-eol</option> option will do this, but it only affects files that have <literal>svn:eol-style = native</literal> properties attached to them. For example, to export a tree with all CRLF line endings (possibly for a Windows .zip file distribution):"
13037 #: ../source/book.xml:18273
13039 msgid "\n$ svn export file:///tmp/repos my-export --native-eol CRLF\nA my-export/test\nA my-export/quiz\n…\nExported revision 15.\n"
13043 #: ../source/book.xml:18280
13044 msgid "You can specify <literal>LR</literal>, <literal>CR</literal>, or <literal>CRLF</literal> as a line ending type with the <option>--native-eol</option> option."
13048 #: ../source/book.xml:18290 ../source/book.xml:21134 ../source/book.xml:22158
13053 #: ../source/book.xml:18293
13058 #: ../source/book.xml:18300
13060 msgid "svn help [SUBCOMMAND...]"
13064 #: ../source/book.xml:18306
13065 msgid "This is your best friend when you're using Subversion and this book isn't within reach!"
13069 #: ../source/book.xml:18313 ../source/book.xml:21160 ../source/book.xml:22183
13074 #: ../source/book.xml:18314
13075 msgid "The options <option>-?</option>, <option>-h</option> and <option>--help</option> have the same effect as using the <command>help</command> subcommand."
13079 #: ../source/book.xml:18334
13081 msgid "\n--config-dir DIR\n"
13085 #: ../source/book.xml:18343
13090 #: ../source/book.xml:18347
13091 msgid "Commit an unversioned file or tree into the repository."
13095 #: ../source/book.xml:18354
13097 msgid "svn import [PATH] URL"
13101 #: ../source/book.xml:18360
13102 msgid "Recursively commit a copy of <replaceable>PATH</replaceable> to <replaceable>URL</replaceable>. If <replaceable>PATH</replaceable> is omitted <quote><filename>.</filename></quote> is assumed. Parent directories are created in the repository as necessary."
13106 #: ../source/book.xml:18378
13111 #: ../source/book.xml:18390
13113 msgid "\n--message (-m) TEXT\n--file (-F) FILE\n--quiet (-q)\n--non-recursive (-N)\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--force-log\n--editor-cmd EDITOR\n--encoding ENC\n--config-dir DIR\n--auto-props\n--no-auto-props\n--ignore-externals\n"
13117 #: ../source/book.xml:18412
13118 msgid "This imports the local directory <filename>myproj</filename> into <filename>trunk/misc</filename> in your repository. The directory <filename>trunk/misc</filename> need not exist before you import into it—<command>svn import</command> will recursively create directories for you."
13122 #: ../source/book.xml:18419
13124 msgid "\n$ svn import -m \"New import\" myproj http://svn.red-bean.com/repos/trunk/misc\nAdding myproj/sample.txt\n…\nTransmitting file data .........\nCommitted revision 16.\n"
13128 #: ../source/book.xml:18426
13129 msgid "Be aware that this will <emphasis>not</emphasis> create a directory named <filename>myproj</filename> in the repository. If that's what you want, simply add <filename>myproj</filename> to the end of the URL:"
13133 #: ../source/book.xml:18430
13135 msgid "\n$ svn import -m \"New import\" myproj http://svn.red-bean.com/repos/trunk/misc/myproj\nAdding myproj/sample.txt\n…\nTransmitting file data .........\nCommitted revision 16.\n"
13139 #: ../source/book.xml:18437
13140 msgid "After importing data, note that the original tree is <emphasis>not</emphasis> under version control. To start working, you still need to <command>svn checkout</command> a fresh working copy of the tree."
13144 #: ../source/book.xml:18447 ../source/book.xml:22253
13149 #: ../source/book.xml:18450
13154 #: ../source/book.xml:18451
13155 msgid "Display information about a local or remote item."
13159 #: ../source/book.xml:18458
13161 msgid "svn info [TARGET[@REV]...]"
13165 #: ../source/book.xml:18464
13166 msgid "Print information about the working copy paths or URLs specified. The information shown for both may include:"
13170 #: ../source/book.xml:18469
13175 #: ../source/book.xml:18472
13180 #: ../source/book.xml:18475
13185 #: ../source/book.xml:18478
13186 msgid "Repository Root"
13190 #: ../source/book.xml:18481
13191 msgid "Repository UUID"
13195 #: ../source/book.xml:18487
13200 #: ../source/book.xml:18490
13201 msgid "Last Changed Author"
13205 #: ../source/book.xml:18493
13206 msgid "Last Changed Revision"
13210 #: ../source/book.xml:18496
13211 msgid "Last Changed Date"
13215 #: ../source/book.xml:18499
13220 #: ../source/book.xml:18502
13225 #: ../source/book.xml:18505
13226 msgid "Lock Created (date)"
13230 #: ../source/book.xml:18508
13231 msgid "Lock Expires (date)"
13235 #: ../source/book.xml:18511
13236 msgid "Additional kinds of information available only for working copy paths are:"
13240 #: ../source/book.xml:18515
13245 #: ../source/book.xml:18518
13246 msgid "Copied From URL"
13250 #: ../source/book.xml:18521
13251 msgid "Copied From Rev"
13255 #: ../source/book.xml:18524
13256 msgid "Text Last Updated"
13260 #: ../source/book.xml:18527
13261 msgid "Properties Last Updated"
13265 #: ../source/book.xml:18530
13270 #: ../source/book.xml:18533
13271 msgid "Conflict Previous Base File"
13275 #: ../source/book.xml:18536
13276 msgid "Conflict Previous Working File"
13280 #: ../source/book.xml:18539
13281 msgid "Conflict Current Base File"
13285 #: ../source/book.xml:18542
13286 msgid "Conflict Properties File"
13290 #: ../source/book.xml:18568
13292 msgid "\n--revision (-r) REV\n--recursive (-R)\n--targets FILENAME\n--incremental\n--xml\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
13296 #: ../source/book.xml:18585
13297 msgid "<command>svn info</command> will show you all the useful information that it has for items in your working copy. It will show information for files:"
13301 #: ../source/book.xml:18588
13303 msgid "\n$ svn info foo.c\nPath: foo.c\nName: foo.c\nURL: http://svn.red-bean.com/repos/test/foo.c\nRepository Root: http://svn.red-bean.com/repos/test\nRepository UUID: 5e7d134a-54fb-0310-bd04-b611643e5c25\nRevision: 4417\nNode Kind: file\nSchedule: normal\nLast Changed Author: sally\nLast Changed Rev: 20\nLast Changed Date: 2003-01-13 16:43:13 -0600 (Mon, 13 Jan 2003)\nText Last Updated: 2003-01-16 21:18:16 -0600 (Thu, 16 Jan 2003)\nProperties Last Updated: 2003-01-13 21:50:19 -0600 (Mon, 13 Jan 2003)\nChecksum: d6aeb60b0662ccceb6bce4bac344cb66\n"
13307 #: ../source/book.xml:18605
13308 msgid "It will also show information for directories:"
13312 #: ../source/book.xml:18606
13314 msgid "\n$ svn info vendors\nPath: vendors\nURL: http://svn.red-bean.com/repos/test/vendors\nRepository Root: http://svn.red-bean.com/repos/test\nRepository UUID: 5e7d134a-54fb-0310-bd04-b611643e5c25\nRevision: 19\nNode Kind: directory\nSchedule: normal\nLast Changed Author: harry\nLast Changed Rev: 19\nLast Changed Date: 2003-01-16 23:21:19 -0600 (Thu, 16 Jan 2003)\nProperties Last Updated: 2003-01-16 23:39:02 -0600 (Thu, 16 Jan 2003)\n"
13318 #: ../source/book.xml:18620
13319 msgid "<command>svn info</command> also acts on URLs (also note that the file readme.doc in this example is locked, so lock information is also provided):"
13323 #: ../source/book.xml:18623
13325 msgid "\n$ svn info http://svn.red-bean.com/repos/test/readme.doc\nPath: readme.doc\nName: readme.doc\nURL: http://svn.red-bean.com/repos/test/readme.doc\nRepository Root: http://svn.red-bean.com/repos/test\nRepository UUID: 5e7d134a-54fb-0310-bd04-b611643e5c25\nRevision: 1\nNode Kind: file\nSchedule: normal\nLast Changed Author: sally\nLast Changed Rev: 42\nLast Changed Date: 2003-01-14 23:21:19 -0600 (Tue, 14 Jan 2003)\nLock Token: opaquelocktoken:14011d4b-54fb-0310-8541-dbd16bd471b2\nLock Owner: harry\nLock Created: 2003-01-15 17:35:12 -0600 (Wed, 15 Jan 2003)\nLock Comment (1 line):\nMy test lock comment\n"
13329 #: ../source/book.xml:18648
13334 #: ../source/book.xml:18652
13335 msgid "List directory entries in the repository."
13339 #: ../source/book.xml:18658
13341 msgid "svn list [TARGET[@REV]...]"
13345 #: ../source/book.xml:18664
13346 msgid "List each <replaceable>TARGET</replaceable> file and the contents of each <replaceable>TARGET</replaceable> directory as they exist in the repository. If <replaceable>TARGET</replaceable> is a working copy path, the corresponding repository URL will be used."
13350 #: ../source/book.xml:18669
13351 msgid "The default <replaceable>TARGET</replaceable> is <quote><filename>.</filename></quote>, meaning the repository URL of the current working copy directory."
13355 #: ../source/book.xml:18673
13356 msgid "With <option>--verbose</option>, <command>svn list</command> shows the following fields for each item:"
13360 #: ../source/book.xml:18678
13361 msgid "Revision number of the last commit"
13365 #: ../source/book.xml:18682
13366 msgid "Author of the last commit"
13370 #: ../source/book.xml:18685
13371 msgid "If locked, the letter <quote>O</quote> (See <xref linkend=\"svn.ref.svn.c.info\"/> for details)."
13375 #: ../source/book.xml:18688
13376 msgid "Size (in bytes)"
13380 #: ../source/book.xml:18691
13381 msgid "Date and time of the last commit"
13385 #: ../source/book.xml:18695
13386 msgid "With <option>--xml</option>, output is in XML format (with a header and an enclosing document element unless <option>--incremental</option> is also specified). All of the information is present; the <option>--verbose</option> option is not accepted."
13390 #: ../source/book.xml:18705
13395 #: ../source/book.xml:18723
13397 msgid "\n--revision (-r) REV\n--verbose (-v)\n--recursive (-R)\n--incremental\n--xml\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
13401 #: ../source/book.xml:18740
13402 msgid "<command>svn list</command> is most useful if you want to see what files a repository has without downloading a working copy:"
13406 #: ../source/book.xml:18743
13408 msgid "\n$ svn list http://svn.red-bean.com/repos/test/support\nREADME.txt\nINSTALL\nexamples/\n…\n"
13412 #: ../source/book.xml:18750
13413 msgid "You can pass the <option>--verbose</option> option for additional information, rather like the UNIX command <command>ls -l</command>:"
13417 #: ../source/book.xml:18753
13419 msgid "\n$ svn list --verbose file:///tmp/repos\n 16 sally 28361 Jan 16 23:18 README.txt\n 27 sally 0 Jan 18 15:27 INSTALL\n 24 harry Jan 18 11:27 examples/\n"
13423 #: ../source/book.xml:18759
13424 msgid "For further details, see <xref linkend=\"svn.tour.history.browsing.list\"/>."
13428 #: ../source/book.xml:18766 ../source/book.xml:22301
13433 #: ../source/book.xml:18769
13438 #: ../source/book.xml:18770
13439 msgid "Lock working copy paths or URLs in the repository, so that no other user can commit changes to them."
13443 #: ../source/book.xml:18778
13445 msgid "svn lock TARGET..."
13449 #: ../source/book.xml:18784
13450 msgid "Lock each <replaceable>TARGET</replaceable>. If any <replaceable>TARGET</replaceable> is already locked by another user, print a warning and continue locking the rest of the <replaceable>TARGET</replaceable>s. Use <option>--force</option> to steal a lock from another user or working copy."
13454 #: ../source/book.xml:18801 ../source/book.xml:20586
13455 msgid "Working Copy, Repository"
13459 #: ../source/book.xml:18813
13461 msgid "\n--targets FILENAME\n--message (-m) TEXT\n--file (-F) FILE\n--force-log\n--encoding ENC\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n--force\n"
13465 #: ../source/book.xml:18831
13466 msgid "Lock two files in your working copy:"
13470 #: ../source/book.xml:18832
13472 msgid "\n\n$ svn lock tree.jpg house.jpg\n'tree.jpg' locked by user 'harry'.\n'house.jpg' locked by user 'harry'.\n"
13476 #: ../source/book.xml:18838
13477 msgid "Lock a file in your working copy that is currently locked by another user:"
13481 #: ../source/book.xml:18840
13483 msgid "\n$ svn lock tree.jpg\nsvn: warning: Path '/tree.jpg is already locked by user 'sally in \\\n filesystem '/svn/repos/db'\n\n$ svn lock --force tree.jpg\n'tree.jpg' locked by user 'harry'.\n"
13487 #: ../source/book.xml:18848
13488 msgid "Lock a file without a working copy:"
13492 #: ../source/book.xml:18849
13494 msgid "\n$ svn lock http://svn.red-bean.com/repos/test/tree.jpg\n'tree.jpg' locked by user 'harry'.\n"
13498 #: ../source/book.xml:18853 ../source/book.xml:20632
13499 msgid "For further details, see <xref linkend=\"svn.advanced.locking\"/>."
13503 #: ../source/book.xml:18860 ../source/book.xml:22350
13508 #: ../source/book.xml:18864
13509 msgid "Display commit log messages."
13513 #: ../source/book.xml:18870
13515 msgid "svn log [PATH]"
13519 #: ../source/book.xml:18871
13521 msgid "svn log URL [PATH...]"
13525 #: ../source/book.xml:18872
13527 msgid "svn log URL[@REV] [PATH...]"
13531 #: ../source/book.xml:18878
13532 msgid "Shows log messages from the repository. If no arguments are supplied, <command>svn log</command> 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 <literal>BASE:1</literal>."
13536 #: ../source/book.xml:18886
13537 msgid "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 <literal>HEAD:1</literal>."
13541 #: ../source/book.xml:18891
13542 msgid "With <option>--verbose</option>, <command>svn log</command> will also print all affected paths with each log message. With <option>--quiet</option>, <command>svn log</command> will not print the log message body itself (this is compatible with <option>--verbose</option>)."
13546 #: ../source/book.xml:18896
13547 msgid "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 <option>--stop-on-copy</option> to disable this behavior, which can be useful for determining branch points."
13551 #: ../source/book.xml:18925
13553 msgid "\n--revision (-r) REV\n--quiet (-q)\n--verbose (-v)\n--targets FILENAME\n--stop-on-copy\n--incremental\n--limit NUM\n--xml\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
13557 #: ../source/book.xml:18945
13558 msgid "You can see the log messages for all the paths that changed in your working copy by running <command>svn log</command> from the top:"
13562 #: ../source/book.xml:18948
13564 msgid "\n$ svn log\n------------------------------------------------------------------------\nr20 | harry | 2003-01-17 22:56:19 -0600 (Fri, 17 Jan 2003) | 1 line\n\nTweak.\n------------------------------------------------------------------------\nr17 | sally | 2003-01-16 23:21:19 -0600 (Thu, 16 Jan 2003) | 2 lines\n…\n"
13568 #: ../source/book.xml:18958
13569 msgid "Examine all log messages for a particular file in your working copy:"
13573 #: ../source/book.xml:18960
13575 msgid "\n$ svn log foo.c\n------------------------------------------------------------------------\nr32 | sally | 2003-01-13 00:43:13 -0600 (Mon, 13 Jan 2003) | 1 line\n\nAdded defines.\n------------------------------------------------------------------------\nr28 | sally | 2003-01-07 21:48:33 -0600 (Tue, 07 Jan 2003) | 3 lines\n…\n"
13579 #: ../source/book.xml:18970
13580 msgid "If you don't have a working copy handy, you can log a URL:"
13584 #: ../source/book.xml:18972
13586 msgid "\n$ svn log http://svn.red-bean.com/repos/test/foo.c\n------------------------------------------------------------------------\nr32 | sally | 2003-01-13 00:43:13 -0600 (Mon, 13 Jan 2003) | 1 line\n\nAdded defines.\n------------------------------------------------------------------------\nr28 | sally | 2003-01-07 21:48:33 -0600 (Tue, 07 Jan 2003) | 3 lines\n…\n"
13590 #: ../source/book.xml:18982
13591 msgid "If you want several distinct paths underneath the same URL, you can use the <literal>URL [PATH...]</literal> syntax."
13595 #: ../source/book.xml:18985
13597 msgid "\n$ svn log http://svn.red-bean.com/repos/test/ foo.c bar.c\n------------------------------------------------------------------------\nr32 | sally | 2003-01-13 00:43:13 -0600 (Mon, 13 Jan 2003) | 1 line\n\nAdded defines.\n------------------------------------------------------------------------\nr31 | harry | 2003-01-10 12:25:08 -0600 (Fri, 10 Jan 2003) | 1 line\n\nAdded new file bar.c\n------------------------------------------------------------------------\nr28 | sally | 2003-01-07 21:48:33 -0600 (Tue, 07 Jan 2003) | 3 lines\n…\n"
13601 #: ../source/book.xml:18999
13602 msgid "When you're concatenating the results of multiple calls to the log command, you may want to use the <option>--incremental</option> option. <command>svn log</command> 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 <command>svn log</command> on a range of two revisions, you would get this:"
13606 #: ../source/book.xml:19007
13608 msgid "\n$ svn log -r 14:15\n------------------------------------------------------------------------\nr14 | …\n\n------------------------------------------------------------------------\nr15 | …\n\n------------------------------------------------------------------------\n"
13612 #: ../source/book.xml:19017
13613 msgid "However, if you wanted to gather 2 non-sequential log messages into a file, you might do something like this:"
13617 #: ../source/book.xml:19020
13619 msgid "\n$ svn log -r 14 > mylog\n$ svn log -r 19 >> mylog\n$ svn log -r 27 >> mylog\n$ cat mylog\n------------------------------------------------------------------------\nr14 | …\n\n------------------------------------------------------------------------\n------------------------------------------------------------------------\nr19 | …\n\n------------------------------------------------------------------------\n------------------------------------------------------------------------\nr27 | …\n\n------------------------------------------------------------------------\n"
13623 #: ../source/book.xml:19038
13624 msgid "You can avoid the clutter of the double dashed lines in your output by using the incremental option:"
13628 #: ../source/book.xml:19040
13630 msgid "\n$ svn log --incremental -r 14 > mylog\n$ svn log --incremental -r 19 >> mylog\n$ svn log --incremental -r 27 >> mylog\n$ cat mylog\n------------------------------------------------------------------------\nr14 | …\n\n------------------------------------------------------------------------\nr19 | …\n\n------------------------------------------------------------------------\nr27 | …\n"
13634 #: ../source/book.xml:19054
13635 msgid "The <option>--incremental</option> option provides similar output control when using the <option>--xml</option> option."
13639 #: ../source/book.xml:19058
13640 msgid "If you run <command>svn log</command> on a specific path and provide a specific revision and get no output at all"
13644 #: ../source/book.xml:19061
13646 msgid "\n$ svn log -r 20 http://svn.red-bean.com/untouched.txt\n------------------------------------------------------------------------\n"
13650 #: ../source/book.xml:19065
13651 msgid "That just means that the path was not modified in that revision. If you log from the top of the repository, or know the file that changed in that revision, you can specify it explicitly:"
13655 #: ../source/book.xml:19069
13657 msgid "\n$ svn log -r 20 touched.txt \n------------------------------------------------------------------------\nr20 | sally | 2003-01-17 22:56:19 -0600 (Fri, 17 Jan 2003) | 1 line\n\nMade a change.\n------------------------------------------------------------------------\n"
13661 #: ../source/book.xml:19084
13666 #: ../source/book.xml:19087
13671 #: ../source/book.xml:19088
13672 msgid "Apply the differences between two sources to a working copy path."
13676 #: ../source/book.xml:19095
13678 msgid "svn merge [-c M | -r N:M] SOURCE[@REV] [WCPATH]"
13682 #: ../source/book.xml:19096
13684 msgid "svn merge sourceURL1[@N] sourceURL2[@M] [WCPATH]"
13688 #: ../source/book.xml:19097
13690 msgid "svn merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]"
13694 #: ../source/book.xml:19103
13695 msgid "In the first and second forms, the source paths (URLs in the first form, working copy paths in the second) are specified at revisions <replaceable>N</replaceable> and <replaceable>M</replaceable>. These are the two sources to be compared. The revisions default to <literal>HEAD</literal> if omitted."
13699 #: ../source/book.xml:19109
13700 msgid "The <literal>-c M</literal> option is equivalent to <literal>-r N:M</literal> where <replaceable>N = M-1</replaceable>. Using <literal>-c -M</literal> does the reverse: <literal>-r M:N</literal> where <replaceable>N = M-1</replaceable>."
13704 #: ../source/book.xml:19114
13705 msgid "In the third form, <replaceable>SOURCE</replaceable> can be a URL or working copy item, in which case the corresponding URL is used. This URL, at revisions <replaceable>N</replaceable> and <replaceable>M</replaceable>, defines the two sources to be compared."
13709 #: ../source/book.xml:19120
13710 msgid "<replaceable>WCPATH</replaceable> is the working copy path that will receive the changes. If <replaceable>WCPATH</replaceable> is omitted, a default value of <quote><filename>.</filename></quote> is assumed, unless the sources have identical basenames that match a file within <quote><filename>.</filename></quote>: in which case, the differences will be applied to that file."
13714 #: ../source/book.xml:19127
13715 msgid "Unlike <command>svn diff</command>, 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."
13719 #: ../source/book.xml:19149
13720 msgid "Only if working with URLs"
13724 #: ../source/book.xml:19155
13726 msgid "\n--revision (-r) REV\n--change (-c) REV\n--non-recursive (-N)\n--quiet (-q)\n--force\n--dry-run\n--diff3-cmd CMD\n--extensions (-x) ARG\n--ignore-ancestry\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
13730 #: ../source/book.xml:19176
13731 msgid "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):"
13735 #: ../source/book.xml:19179
13737 msgid "\n$ svn merge -r 250:HEAD http://svn.red-bean.com/repos/branches/my-branch\nU myproj/tiny.txt\nU myproj/thhgttg.txt\nU myproj/win.txt\nU myproj/flo.txt\n"
13741 #: ../source/book.xml:19186
13742 msgid "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:"
13746 #: ../source/book.xml:19189
13748 msgid "\n$ svn merge -r 23:30 file:///tmp/repos/trunk/vendors\nU myproj/thhgttg.txt\n…\n"
13752 #: ../source/book.xml:19194
13753 msgid "To merge changes to a single file:"
13757 #: ../source/book.xml:19195
13759 msgid "\n$ cd myproj\n$ svn merge -r 30:31 thhgttg.txt \nU thhgttg.txt\n"
13763 #: ../source/book.xml:19206
13768 #: ../source/book.xml:19209
13773 #: ../source/book.xml:19210
13774 msgid "Create a new directory under version control."
13778 #: ../source/book.xml:19216
13780 msgid "svn mkdir PATH..."
13784 #: ../source/book.xml:19217
13786 msgid "svn mkdir URL..."
13790 #: ../source/book.xml:19223
13791 msgid "Create a directory with a name given by the final component of the <replaceable>PATH</replaceable> or URL. A directory specified by a working copy <replaceable>PATH</replaceable> 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."
13795 #: ../source/book.xml:19243 ../source/book.xml:19346
13796 msgid "Working copy, repository if operating on a URL"
13800 #: ../source/book.xml:19249 ../source/book.xml:19352 ../source/book.xml:19438 ../source/book.xml:19518 ../source/book.xml:19596 ../source/book.xml:19677 ../source/book.xml:19772
13801 msgid "Only if operating on a URL"
13805 #: ../source/book.xml:19255
13807 msgid "\n--message (-m) TEXT\n--file (-F) FILE\n--quiet (-q)\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--editor-cmd EDITOR\n--encoding ENC\n--force-log\n--config-dir DIR\n"
13811 #: ../source/book.xml:19273
13812 msgid "Create a directory in your working copy:"
13816 #: ../source/book.xml:19274
13818 msgid "\n$ svn mkdir newdir\nA newdir\n"
13822 #: ../source/book.xml:19278
13823 msgid "Create one in the repository (instant commit, so a log message is required):"
13827 #: ../source/book.xml:19280
13829 msgid "\n$ svn mkdir -m \"Making a new dir.\" http://svn.red-bean.com/repos/newdir\n\nCommitted revision 26.\n"
13833 #: ../source/book.xml:19291
13838 #: ../source/book.xml:19295
13839 msgid "Move a file or directory."
13843 #: ../source/book.xml:19301
13845 msgid "svn move SRC DST"
13849 #: ../source/book.xml:19307
13850 msgid "This command moves a file or directory in your working copy or in the repository."
13854 #: ../source/book.xml:19310
13855 msgid "This command is equivalent to an <command>svn copy</command> followed by <command>svn delete</command>."
13859 #: ../source/book.xml:19315
13860 msgid "Subversion does not support moving between working copies and URLs. In addition, you can only move files within a single repository—Subversion does not support cross-repository moving."
13864 #: ../source/book.xml:19324
13865 msgid "Move and schedule a file or directory for addition (with history)."
13869 #: ../source/book.xml:19331
13870 msgid "Complete server-side rename."
13874 #: ../source/book.xml:19340
13875 msgid "mv, rename, ren"
13879 #: ../source/book.xml:19361
13884 #: ../source/book.xml:19358
13886 msgid "\n--message (-m) TEXT\n--file (-F) FILE\n--revision (-r) REV (<placeholder-1/>)\n--quiet (-q)\n--force\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--editor-cmd EDITOR\n--encoding ENC\n--force-log\n--config-dir DIR\n"
13890 #: ../source/book.xml:19378
13891 msgid "Move a file in your working copy:"
13895 #: ../source/book.xml:19379
13897 msgid "\n$ svn move foo.c bar.c\nA bar.c\nD foo.c\n"
13901 #: ../source/book.xml:19384
13902 msgid "Move a file in the repository (an immediate commit, so it requires a commit message):"
13906 #: ../source/book.xml:19386
13908 msgid "\n$ svn move -m \"Move a file\" http://svn.red-bean.com/repos/foo.c \\\n http://svn.red-bean.com/repos/bar.c\n\nCommitted revision 27.\n"
13912 #: ../source/book.xml:19398
13917 #: ../source/book.xml:19401
13918 msgid "svn propdel"
13922 #: ../source/book.xml:19402
13923 msgid "Remove a property from an item."
13927 #: ../source/book.xml:19408
13929 msgid "svn propdel PROPNAME [PATH...]"
13933 #: ../source/book.xml:19409
13935 msgid "svn propdel PROPNAME --revprop -r REV [TARGET]"
13939 #: ../source/book.xml:19415
13940 msgid "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 (<replaceable>TARGET</replaceable> only determines which repository to access)."
13944 #: ../source/book.xml:19426
13949 #: ../source/book.xml:19432 ../source/book.xml:19512 ../source/book.xml:19590 ../source/book.xml:19671 ../source/book.xml:19766
13950 msgid "Working copy, repository only if operating on a URL"
13954 #: ../source/book.xml:19444
13956 msgid "\n--quiet (-q)\n--recursive (-R)\n--revision (-r) REV\n--revprop\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
13960 #: ../source/book.xml:19460
13961 msgid "Delete a property from a file in your working copy"
13965 #: ../source/book.xml:19462
13967 msgid "\n$ svn propdel svn:mime-type some-script\nproperty 'svn:mime-type' deleted from 'some-script'.\n"
13971 #: ../source/book.xml:19466
13972 msgid "Delete a revision property:"
13976 #: ../source/book.xml:19467
13978 msgid "\n$ svn propdel --revprop -r 26 release-date \nproperty 'release-date' deleted from repository revision '26'\n"
13982 #: ../source/book.xml:19477
13987 #: ../source/book.xml:19480
13988 msgid "svn propedit"
13992 #: ../source/book.xml:19481
13993 msgid "Edit the property of one or more items under version control."
13997 #: ../source/book.xml:19488
13999 msgid "svn propedit PROPNAME PATH..."
14003 #: ../source/book.xml:19489
14005 msgid "svn propedit PROPNAME --revprop -r REV [TARGET]"
14009 #: ../source/book.xml:19495
14010 msgid "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 (<replaceable>TARGET</replaceable> only determines which repository to access)."
14014 #: ../source/book.xml:19506
14019 #: ../source/book.xml:19524
14021 msgid "\n--revision (-r) REV\n--revprop\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--encoding ENC\n--editor-cmd EDITOR\n--config-dir DIR\n"
14025 #: ../source/book.xml:19540
14026 msgid "<command>svn propedit</command> makes it easy to modify properties that have multiple values:"
14030 #: ../source/book.xml:19542
14032 msgid "\n$ svn propedit svn:keywords foo.c \n <svn will launch your favorite editor here, with a buffer open\n containing the current contents of the svn:keywords property. You\n can add multiple values to a property easily here by entering one\n value per line.>\nSet new value for property 'svn:keywords' on 'foo.c'\n"
14036 #: ../source/book.xml:19556 ../source/book.xml:22394
14041 #: ../source/book.xml:19559
14042 msgid "svn propget"
14046 #: ../source/book.xml:19560
14047 msgid "Print the value of a property."
14051 #: ../source/book.xml:19566
14053 msgid "svn propget PROPNAME [TARGET[@REV]...]"
14057 #: ../source/book.xml:19567
14059 msgid "svn propget PROPNAME --revprop -r REV [URL]"
14063 #: ../source/book.xml:19573
14064 msgid "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 <xref linkend=\"svn.advanced.props\"/> for more information on properties."
14068 #: ../source/book.xml:19584
14073 #: ../source/book.xml:19602
14075 msgid "\n--recursive (-R)\n--revision (-r) REV\n--revprop\n--strict\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
14079 #: ../source/book.xml:19618
14080 msgid "Examine a property of a file in your working copy:"
14084 #: ../source/book.xml:19620
14086 msgid "\n$ svn propget svn:keywords foo.c\nAuthor\nDate\nRev\n"
14090 #: ../source/book.xml:19626
14091 msgid "The same goes for a revision property:"
14095 #: ../source/book.xml:19627
14097 msgid "\n$ svn propget svn:log --revprop -r 20 \nBegan journal.\n"
14101 #: ../source/book.xml:19637 ../source/book.xml:22447
14106 #: ../source/book.xml:19640
14107 msgid "svn proplist"
14111 #: ../source/book.xml:19641
14112 msgid "List all properties."
14116 #: ../source/book.xml:19647
14118 msgid "svn proplist [TARGET[@REV]...]"
14122 #: ../source/book.xml:19648
14124 msgid "svn proplist --revprop -r REV [TARGET]"
14128 #: ../source/book.xml:19654
14129 msgid "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 (<replaceable>TARGET</replaceable> only determines which repository to access)."
14133 #: ../source/book.xml:19665
14138 #: ../source/book.xml:19683
14140 msgid "\n--verbose (-v)\n--recursive (-R)\n--revision (-r) REV\n--quiet (-q)\n--revprop\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
14144 #: ../source/book.xml:19700
14145 msgid "You can use proplist to see the properties on an item in your working copy:"
14149 #: ../source/book.xml:19702
14151 msgid "\n$ svn proplist foo.c\nProperties on 'foo.c':\n svn:mime-type\n svn:keywords\n owner\n"
14155 #: ../source/book.xml:19709
14156 msgid "But with the <option>--verbose</option> flag, svn proplist is extremely handy as it also shows you the values for the properties:"
14160 #: ../source/book.xml:19712
14162 msgid "\n$ svn proplist --verbose foo.c\nProperties on 'foo.c':\n svn:mime-type : text/plain\n svn:keywords : Author Date Rev\n owner : sally\n"
14166 #: ../source/book.xml:19725
14171 #: ../source/book.xml:19728
14172 msgid "svn propset"
14176 #: ../source/book.xml:19729
14177 msgid "Set PROPNAME to PROPVAL on files, directories, or revisions."
14181 #: ../source/book.xml:19735
14183 msgid "svn propset PROPNAME [PROPVAL | -F VALFILE] PATH..."
14187 #: ../source/book.xml:19736
14189 msgid "svn propset PROPNAME --revprop -r REV [PROPVAL | -F VALFILE] [TARGET]"
14193 #: ../source/book.xml:19742
14194 msgid "Set <replaceable>PROPNAME</replaceable> to <replaceable>PROPVAL</replaceable> 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 (<replaceable>TARGET</replaceable> only determines which repository to access)."
14198 #: ../source/book.xml:19751
14199 msgid "Subversion has a number of <quote>special</quote> properties that affect its behavior. See <xref linkend=\"svn.ref.properties\"/> for more on these properties."
14203 #: ../source/book.xml:19760
14208 #: ../source/book.xml:19778
14210 msgid "\n--file (-F) FILE\n--quiet (-q)\n--revision (-r) REV\n--targets FILENAME\n--recursive (-R)\n--revprop\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--encoding ENC\n--force\n--config-dir DIR\n"
14214 #: ../source/book.xml:19798
14215 msgid "Set the mime type on a file:"
14219 #: ../source/book.xml:19799
14221 msgid "\n$ svn propset svn:mime-type image/jpeg foo.jpg \nproperty 'svn:mime-type' set on 'foo.jpg'\n"
14225 #: ../source/book.xml:19803
14226 msgid "On a UNIX system, if you want a file to have the executable permission set:"
14230 #: ../source/book.xml:19805
14232 msgid "\n$ svn propset svn:executable ON somescript\nproperty 'svn:executable' set on 'somescript'\n"
14236 #: ../source/book.xml:19809
14237 msgid "Perhaps you have an internal policy to set certain properties for the benefit of your coworkers:"
14241 #: ../source/book.xml:19811
14243 msgid "\n$ svn propset owner sally foo.c\nproperty 'owner' set on 'foo.c'\n"
14247 #: ../source/book.xml:19815
14248 msgid "If you made a mistake in a log message for a particular revision and want to change it, use <option>--revprop</option> and set <literal>svn:log</literal> to the new log message:"
14252 #: ../source/book.xml:19819
14254 msgid "\n$ svn propset --revprop -r 25 svn:log \"Journaled about trip to New York.\"\nproperty 'svn:log' set on repository revision '25'\n"
14258 #: ../source/book.xml:19823
14259 msgid "Or, if you don't have a working copy, you can provide a URL."
14263 #: ../source/book.xml:19825
14265 msgid "\n$ svn propset --revprop -r 26 svn:log \"Document nap.\" http://svn.red-bean.com/repos\nproperty 'svn:log' set on repository revision '25'\n"
14269 #: ../source/book.xml:19829
14270 msgid "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:"
14274 #: ../source/book.xml:19832
14276 msgid "\n$ svn propset owner-pic -F sally.jpg moo.c \nproperty 'owner-pic' set on 'moo.c'\n"
14280 #: ../source/book.xml:19837
14281 msgid "By default, you cannot modify revision properties in a Subversion repository. Your repository administrator must explicitly enable revision property modifications by creating a hook named <literal>pre-revprop-change</literal>. See <xref linkend=\"svn.reposadmin.create.hooks\"/> for more information on hook scripts."
14285 #: ../source/book.xml:19850
14290 #: ../source/book.xml:19854
14295 #: ../source/book.xml:19854
14296 msgid "Remove <placeholder-1/> state on working copy files or directories."
14300 #: ../source/book.xml:19861
14302 msgid "svn resolved PATH..."
14306 #: ../source/book.xml:19867
14307 msgid "Remove <quote>conflicted</quote> state on working copy files or directories. This routine does not semantically resolve conflict markers; it merely removes conflict-related artifact files and allows <replaceable>PATH</replaceable> to be committed again; that is, it tells Subversion that the conflicts have been <quote>resolved</quote>. See <xref linkend=\"svn.tour.cycle.resolve\"/> for an in-depth look at resolving conflicts."
14311 #: ../source/book.xml:19898 ../source/book.xml:19986
14313 msgid "\n--targets FILENAME\n--recursive (-R)\n--quiet (-q)\n--config-dir DIR\n"
14317 #: ../source/book.xml:19909
14318 msgid "If you get a conflict on an update, your working copy will sprout three new files:"
14322 #: ../source/book.xml:19911
14324 msgid "\n$ svn update\nC foo.c\nUpdated to revision 31.\n$ ls\nfoo.c\nfoo.c.mine\nfoo.c.r30\nfoo.c.r31\n"
14328 #: ../source/book.xml:19921
14329 msgid "Once you've resolved the conflict and <filename>foo.c</filename> is ready to be committed, run <command>svn resolved</command> to let your working copy know you've taken care of everything."
14333 #: ../source/book.xml:19926
14334 msgid "You <emphasis>can</emphasis> just remove the conflict files and commit, but <command>svn resolved</command> fixes up some bookkeeping data in the working copy administrative area in addition to removing the conflict files, so we recommend that you use this command."
14338 #: ../source/book.xml:19939
14343 #: ../source/book.xml:19943
14344 msgid "Undo all local edits."
14348 #: ../source/book.xml:19949
14350 msgid "svn revert PATH..."
14354 #: ../source/book.xml:19955
14355 msgid "Reverts any local changes to a file or directory and resolves any conflicted states. <command>svn revert</command> 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 <quote>unscheduled</quote>)."
14359 #: ../source/book.xml:19997
14360 msgid "Discard changes to a file:"
14364 #: ../source/book.xml:19998
14366 msgid "\n$ svn revert foo.c\nReverted foo.c\n"
14370 #: ../source/book.xml:20002
14371 msgid "If you want to revert a whole directory of files, use the <option>--recursive</option> flag:"
14375 #: ../source/book.xml:20004
14377 msgid "\n$ svn revert --recursive .\nReverted newdir/afile\nReverted foo.c\nReverted bar.txt\n"
14381 #: ../source/book.xml:20010
14382 msgid "Lastly, you can undo any scheduling operations:"
14386 #: ../source/book.xml:20012
14388 msgid "\n$ svn add mistake.txt whoops\nA mistake.txt\nA whoops\nA whoops/oopsie.c\n\n$ svn revert mistake.txt whoops\nReverted mistake.txt\nReverted whoops\n\n$ svn status\n? mistake.txt\n? whoops\n"
14392 #: ../source/book.xml:20027
14393 msgid "<command>svn revert</command> is inherently dangerous, since its entire purpose is to throw away data—namely, your uncommitted changes. Once you've reverted, Subversion provides <emphasis>no way</emphasis> to get back those uncommitted changes."
14397 #: ../source/book.xml:20033
14398 msgid "If you provide no targets to <command>svn revert</command>, it will do nothing—to protect you from accidentally losing changes in your working copy, <command>svn revert</command> requires you to provide at least one target."
14402 #: ../source/book.xml:20045
14407 #: ../source/book.xml:20049
14408 msgid "Print the status of working copy files and directories."
14412 #: ../source/book.xml:20055
14414 msgid "svn status [PATH...]"
14418 #: ../source/book.xml:20061
14419 msgid "Print the status of working copy files and directories. With no arguments, it prints only locally modified items (no repository access). With <option>--show-updates</option>, it adds working revision and server out-of-date information. With <option>--verbose</option>, it prints full revision information on every item."
14423 #: ../source/book.xml:20068
14424 msgid "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."
14428 #: ../source/book.xml:20071
14429 msgid "The first column indicates that an item was added, deleted, or otherwise changed."
14433 #: ../source/book.xml:20075 ../source/book.xml:20156 ../source/book.xml:20182 ../source/book.xml:20198 ../source/book.xml:20214 ../source/book.xml:20229 ../source/book.xml:20277
14438 #: ../source/book.xml:20077 ../source/book.xml:20158
14439 msgid "No modifications."
14443 #: ../source/book.xml:20081
14448 #: ../source/book.xml:20083
14449 msgid "Item is scheduled for Addition."
14453 #: ../source/book.xml:20087
14458 #: ../source/book.xml:20089
14459 msgid "Item is scheduled for Deletion."
14463 #: ../source/book.xml:20093 ../source/book.xml:20162
14468 #: ../source/book.xml:20095
14469 msgid "Item has been modified."
14473 #: ../source/book.xml:20099
14478 #: ../source/book.xml:20101
14479 msgid "Item has been replaced in your working copy. This means the file was scheduled for deletion, and then a new file with the same name was scheduled for addition in its place."
14483 #: ../source/book.xml:20108 ../source/book.xml:20169
14488 #: ../source/book.xml:20110
14489 msgid "The contents (as opposed to the properties) of the item conflict with updates received from the repository."
14493 #: ../source/book.xml:20116
14498 #: ../source/book.xml:20118
14499 msgid "Item is present because of an externals definition."
14503 #: ../source/book.xml:20122
14508 #: ../source/book.xml:20124
14509 msgid "Item is being ignored (e.g. with the <literal>svn:ignore</literal> property)."
14513 #: ../source/book.xml:20129
14518 #: ../source/book.xml:20131
14519 msgid "Item is not under version control."
14523 #: ../source/book.xml:20135
14528 #: ../source/book.xml:20137
14529 msgid "Item is missing (e.g. you moved or deleted it without using <command>svn</command>). This also indicates that a directory is incomplete (a checkout or update was interrupted)."
14533 #: ../source/book.xml:20144
14538 #: ../source/book.xml:20146
14539 msgid "Item is versioned as one kind of object (file, directory, link), but has been replaced by different kind of object."
14543 #: ../source/book.xml:20152
14544 msgid "The second column tells the status of a file's or directory's properties."
14548 #: ../source/book.xml:20164
14549 msgid "Properties for this item have been modified."
14553 #: ../source/book.xml:20171
14554 msgid "Properties for this item are in conflict with property updates received from the repository."
14558 #: ../source/book.xml:20177
14559 msgid "The third column is populated only if the working copy directory is locked. (See <xref linkend=\"svn.tour.cleanup\"/>.)"
14563 #: ../source/book.xml:20184
14564 msgid "Item is not locked."
14568 #: ../source/book.xml:20188
14573 #: ../source/book.xml:20190
14574 msgid "Item is locked."
14578 #: ../source/book.xml:20194
14579 msgid "The fourth column is populated only if the item is scheduled for addition-with-history."
14583 #: ../source/book.xml:20200
14584 msgid "No history scheduled with commit."
14588 #: ../source/book.xml:20204
14593 #: ../source/book.xml:20206
14594 msgid "History scheduled with commit."
14598 #: ../source/book.xml:20210
14599 msgid "The fifth column is populated only if the item is switched relative to its parent (see <xref linkend=\"svn.branchmerge.switchwc\"/>)."
14603 #: ../source/book.xml:20216
14604 msgid "Item is a child of its parent directory."
14608 #: ../source/book.xml:20220
14613 #: ../source/book.xml:20222
14614 msgid "Item is switched."
14618 #: ../source/book.xml:20226
14619 msgid "The sixth column is populated with lock information."
14623 #: ../source/book.xml:20231
14624 msgid "When <option>--show-updates</option> is used, the file is not locked. If <option>--show-updates</option> is <emphasis>not</emphasis> used, this merely means that the file is not locked in this working copy."
14628 #: ../source/book.xml:20239
14633 #: ../source/book.xml:20241
14634 msgid "File is locked in this working copy."
14638 #: ../source/book.xml:20245
14643 #: ../source/book.xml:20247
14644 msgid "File is locked either by another user or in another working copy. This only appears when <option>--show-updates</option> is used."
14648 #: ../source/book.xml:20253
14653 #: ../source/book.xml:20255
14654 msgid "File was locked in this working copy, but the lock has been <quote>stolen</quote> and is invalid. The file is currently locked in the repository. This only appears when <option>--show-updates</option> is used."
14658 #: ../source/book.xml:20263
14663 #: ../source/book.xml:20265
14664 msgid "File was locked in this working copy, but the lock has been <quote>broken</quote> and is invalid. The file is no longer locked This only appears when <option>--show-updates</option> is used."
14668 #: ../source/book.xml:20272
14669 msgid "The out-of-date information appears in the seventh column (only if you pass the <option>--show-updates</option> option)."
14673 #: ../source/book.xml:20279
14674 msgid "The item in your working copy is up-to-date."
14678 #: ../source/book.xml:20283
14683 #: ../source/book.xml:20285
14684 msgid "A newer revision of the item exists on the server."
14688 #: ../source/book.xml:20290
14689 msgid "The remaining fields are variable width and delimited by spaces. The working revision is the next field if the <option>--show-updates</option> or <option>--verbose</option> options are passed."
14693 #: ../source/book.xml:20294
14694 msgid "If the <option>--verbose</option> option is passed, the last committed revision and last committed author are displayed next."
14698 #: ../source/book.xml:20297
14699 msgid "The working copy path is always the final field, so it can include spaces."
14703 #: ../source/book.xml:20304
14708 #: ../source/book.xml:20316
14709 msgid "Only if using <option>--show-updates</option>"
14713 #: ../source/book.xml:20322
14715 msgid "\n--show-updates (-u)\n--verbose (-v)\n--non-recursive (-N)\n--quiet (-q)\n--no-ignore\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n--ignore-externals\n"
14719 #: ../source/book.xml:20340
14720 msgid "This is the easiest way to find out what changes you have made to your working copy:"
14724 #: ../source/book.xml:20342
14726 msgid "\n$ svn status wc\n M wc/bar.c\nA + wc/qax.c\n"
14730 #: ../source/book.xml:20347
14731 msgid "If you want to find out what files in your working copy are out-of-date, pass the <option>--show-updates</option> option (this will <emphasis>not</emphasis> make any changes to your working copy). Here you can see that <filename>wc/foo.c</filename> has changed in the repository since we last updated our working copy:"
14735 #: ../source/book.xml:20355
14737 msgid "\n$ svn status --show-updates wc\n M 965 wc/bar.c\n * 965 wc/foo.c\nA + 965 wc/qax.c\nStatus against revision: 981\n"
14741 #: ../source/book.xml:20363
14742 msgid "<option>--show-updates</option><emphasis>only</emphasis> places an asterisk next to items that are out of date (that is, items that will be updated from the repository if you run <command>svn update</command>). <option>--show-updates</option> does <emphasis>not</emphasis> cause the status listing to reflect the repository's version of the item (although you can see the revision number in the repository by passing the <option>--verbose</option> option)."
14746 #: ../source/book.xml:20372
14747 msgid "And finally, the most information you can get out of the status subcommand:"
14751 #: ../source/book.xml:20374
14753 msgid "\n$ svn status --show-updates --verbose wc\n M 965 938 sally wc/bar.c\n * 965 922 harry wc/foo.c\nA + 965 687 harry wc/qax.c\n 965 687 harry wc/zig.c\nHead revision: 981\n"
14757 #: ../source/book.xml:20382
14758 msgid "For many more examples of <command>svn status</command>, see <xref linkend=\"svn.tour.cycle.examine.status\"/>."
14762 #: ../source/book.xml:20390
14767 #: ../source/book.xml:20393
14772 #: ../source/book.xml:20394
14773 msgid "Update working copy to a different URL."
14777 #: ../source/book.xml:20400
14779 msgid "svn switch URL [PATH]"
14783 #: ../source/book.xml:20401
14785 msgid "switch --relocate FROM TO [PATH...]"
14789 #: ../source/book.xml:20407
14790 msgid "The first variant of this subcommand (without the <option>--relocate</option> option) updates your working copy to point to 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 <xref linkend=\"svn.branchmerge.switchwc\"/> for an in-depth look at switching."
14794 #: ../source/book.xml:20414
14795 msgid "The <option>--relocate</option> option causes <command>svn switch</command> to do something different: it updates your working copy to point to <emphasis>the same</emphasis> repository directory, only at a different URL (typically because an administrator has moved the repository to another server, or to another URL on the same server)."
14799 #: ../source/book.xml:20427
14804 #: ../source/book.xml:20445
14806 msgid "\n--revision (-r) REV\n--non-recursive (-N)\n--quiet (-q)\n--diff3-cmd CMD\n--relocate FROM TO\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n"
14810 #: ../source/book.xml:20462
14811 msgid "If you're currently inside the directory <filename>vendors</filename>, which was branched to <filename>vendors-with-fix</filename>, and you'd like to switch your working copy to that branch:"
14815 #: ../source/book.xml:20466
14817 msgid "\n$ svn switch http://svn.red-bean.com/repos/branches/vendors-with-fix .\nU myproj/foo.txt\nU myproj/bar.txt\nU myproj/baz.c\nU myproj/qux.c\nUpdated to revision 31.\n"
14821 #: ../source/book.xml:20474
14822 msgid "And to switch back, just provide the URL to the location in the repository from which you originally checked out your working copy:"
14826 #: ../source/book.xml:20477
14828 msgid "\n$ svn switch http://svn.red-bean.com/repos/trunk/vendors .\nU myproj/foo.txt\nU myproj/bar.txt\nU myproj/baz.c\nU myproj/qux.c\nUpdated to revision 31.\n"
14832 #: ../source/book.xml:20486
14833 msgid "You can just switch part of your working copy to a branch if you don't want to switch your entire working copy."
14837 #: ../source/book.xml:20490
14838 msgid "Sometimes an administrator might change the <quote>base location</quote> of your repository—in other words, the contents of the repository doesn't change, but the main URL used to reach the root of the repository does. For example, the hostname may change, the URL scheme may change, or any part of the URL which leads to the repository itself may change. Rather than check out a new working copy, you can have the <command>svn switch</command> command <quote>rewrite</quote> the beginnings of all the URLs in your working copy. Use the <option>--relocate</option> option to do the substitution. No file contents are changed, nor is the repository contacted. It's similar to running a Perl script over your working copy <filename>.svn/</filename> directories which runs <command>s/OldRoot/NewRoot/</command>."
14842 #: ../source/book.xml:20505
14844 msgid "\n$ svn checkout file:///tmp/repos test\nA test/a\nA test/b\n…\n\n$ mv repos newlocation\n$ cd test/\n\n$ svn update\nsvn: Unable to open an ra_local session to URL\nsvn: Unable to open repository 'file:///tmp/repos'\n\n$ svn switch --relocate file:///tmp/repos file:///tmp/newlocation .\n$ svn update\nAt revision 3.\n"
14848 #: ../source/book.xml:20523
14849 msgid "Be careful when using the <option>--relocate</option> option. If you mistype the argument, you might end up creating nonsensical URLs within your working copy that render the whole workspace unusable and tricky to fix. It's also important to understand exactly when one should or shouldn't use <option>--relocate</option>. Here's the rule of thumb:"
14853 #: ../source/book.xml:20533
14854 msgid "If the working copy needs to reflect a new directory <emphasis>within</emphasis> the repository, then use just <command>svn switch</command>."
14858 #: ../source/book.xml:20539
14859 msgid "If the working copy still reflects the same repository directory, but the location of the repository itself has changed, then use <command>svn switch --relocate</command>."
14863 #: ../source/book.xml:20552
14868 #: ../source/book.xml:20555
14873 #: ../source/book.xml:20556
14874 msgid "Unlock working copy paths or URLs."
14878 #: ../source/book.xml:20562
14880 msgid "svn unlock TARGET..."
14884 #: ../source/book.xml:20568
14885 msgid "Unlock each <replaceable>TARGET</replaceable>. If any <replaceable>TARGET</replaceable> 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 <replaceable>TARGET</replaceable>s. Use <option>--force</option> to break a lock belonging to another user or working copy."
14889 #: ../source/book.xml:20598
14891 msgid "\n--targets FILENAME\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n--force\n"
14895 #: ../source/book.xml:20612
14896 msgid "Unlock two files in your working copy:"
14900 #: ../source/book.xml:20613
14902 msgid "\n\n$ svn unlock tree.jpg house.jpg\n'tree.jpg' unlocked.\n'house.jpg' unlocked.\n"
14906 #: ../source/book.xml:20619
14907 msgid "Unlock a file in your working copy that is currently locked by another user:"
14911 #: ../source/book.xml:20621
14913 msgid "\n$ svn unlock tree.jpg\nsvn: 'tree.jpg' is not locked in this working copy\n$ svn unlock --force tree.jpg\n'tree.jpg' unlocked.\n"
14917 #: ../source/book.xml:20627
14918 msgid "Unlock a file without a working copy:"
14922 #: ../source/book.xml:20628
14924 msgid "\n$ svn unlock http://svn.red-bean.com/repos/test/tree.jpg\n'tree.jpg unlocked.\n"
14928 #: ../source/book.xml:20639
14933 #: ../source/book.xml:20643
14934 msgid "Update your working copy."
14938 #: ../source/book.xml:20649
14940 msgid "svn update [PATH...]"
14944 #: ../source/book.xml:20655
14945 msgid "<command>svn update</command> brings changes from the repository into your working copy. If no revision is given, it brings your working copy up-to-date with the <literal>HEAD</literal> revision. Otherwise, it synchronizes the working copy to the revision given by the <option>--revision</option> option. As part of the synchronization, <command>svn update</command> also removes any stale locks (see <xref linkend=\"svn.tour.cleanup\"/>) found in the working copy."
14949 #: ../source/book.xml:20664
14950 msgid "For each updated item, it prints a line that starts with a character reporting the action taken. These characters have the following meaning:"
14954 #: ../source/book.xml:20669
14959 #: ../source/book.xml:20671
14964 #: ../source/book.xml:20675
14969 #: ../source/book.xml:20677
14974 #: ../source/book.xml:20681
14979 #: ../source/book.xml:20683
14984 #: ../source/book.xml:20687
14989 #: ../source/book.xml:20689
14994 #: ../source/book.xml:20693
14999 #: ../source/book.xml:20695
15004 #: ../source/book.xml:20699
15005 msgid "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."
15009 #: ../source/book.xml:20707
15014 #: ../source/book.xml:20725
15016 msgid "\n--revision (-r) REV\n--non-recursive (-N)\n--quiet (-q)\n--no-ignore\n--incremental\n--diff3-cmd CMD\n--username USER\n--password PASS\n--no-auth-cache\n--non-interactive\n--config-dir DIR\n--ignore-externals\n"
15020 #: ../source/book.xml:20744
15021 msgid "Pick up repository changes that have happened since your last update:"
15025 #: ../source/book.xml:20746
15027 msgid "\n$ svn update\nA newdir/toggle.c\nA newdir/disclose.c\nA newdir/launch.c\nD newdir/README\nUpdated to revision 32.\n"
15031 #: ../source/book.xml:20754
15032 msgid "You can also <quote>update</quote> your working copy to an older revision (Subversion doesn't have the concept of <quote>sticky</quote> files like CVS does; see <xref linkend=\"svn.forcvs\"/>):"
15036 #: ../source/book.xml:20757
15038 msgid "\n$ svn update -r30\nA newdir/README\nD newdir/toggle.c\nD newdir/disclose.c\nD newdir/launch.c\nU foo.c\nUpdated to revision 30.\n"
15042 #: ../source/book.xml:20767
15043 msgid "If you want to examine an older revision of a single file, you may want to use <command>svn cat</command> instead—it won't change your working copy."
15047 #: ../source/book.xml:20784
15048 msgid "<command>svnadmin</command> is the administrative tool for monitoring and repairing your Subversion repository. For detailed information, see <xref linkend=\"svn.reposadmin.maint.tk.svnadmin\"/>."
15052 #: ../source/book.xml:20787
15053 msgid "Since <command>svnadmin</command> works via direct repository access (and thus can only be used on the machine that holds the repository), it refers to the repository with a path, not a URL."
15057 #: ../source/book.xml:20793
15058 msgid "<command>svnadmin</command> Options"
15062 #: ../source/book.xml:20798
15063 msgid "--bdb-log-keep"
15067 #: ../source/book.xml:20801
15068 msgid "(Berkeley DB specific) Disable automatic log removal of database log files. Having these log files around can be convenient if you need to restore from a catastrophic repository failure."
15072 #: ../source/book.xml:20809
15073 msgid "--bdb-txn-nosync"
15077 #: ../source/book.xml:20812
15078 msgid "(Berkeley DB specific) Disables fsync when committing database transactions. Used with the <command>svnadmin create</command> command to create a Berkeley DB backed repository with <literal>DB_TXN_NOSYNC</literal> enabled (which improves speed but has some risks associated with it)."
15082 #: ../source/book.xml:20822
15083 msgid "--bypass-hooks"
15087 #: ../source/book.xml:20825
15088 msgid "Bypass the repository hook system."
15092 #: ../source/book.xml:20830
15093 msgid "--clean-logs"
15097 #: ../source/book.xml:20833
15098 msgid "Removes unused Berkeley DB logs."
15102 #: ../source/book.xml:20839
15103 msgid "--force-uuid"
15107 #: ../source/book.xml:20842
15108 msgid "By default, when loading data into repository that already contains revisions, <command>svnadmin</command> will ignore the <literal>UUID</literal> from the dump stream. This option will cause the repository's <literal>UUID</literal> to be set to the <literal>UUID</literal> from the stream."
15112 #: ../source/book.xml:20852
15113 msgid "--ignore-uuid"
15117 #: ../source/book.xml:20855
15118 msgid "By default, when loading an empty repository, <command>svnadmin</command> will ignore the <literal>UUID</literal> from the dump stream. This option will force that UUID to be ignored (useful for overriding your configuration file if it has <option>--force-uuid</option> set)."
15122 #: ../source/book.xml:20868
15123 msgid "Dump a revision only as a diff against the previous revision, instead of the usual fulltext."
15127 #: ../source/book.xml:20875
15128 msgid "--parent-dir <placeholder-1/>"
15132 #: ../source/book.xml:20879
15133 msgid "When loading a dump file, root paths at <replaceable>DIR</replaceable> instead of <filename>/</filename>."
15137 #: ../source/book.xml:20885
15138 msgid "<option>--revision</option> (<option>-r</option>) <replaceable>ARG</replaceable>"
15142 #: ../source/book.xml:20888
15143 msgid "Specify a particular revision to operate on."
15147 #: ../source/book.xml:20894
15152 #: ../source/book.xml:20897
15153 msgid "Do not show normal progress—show only errors."
15157 #: ../source/book.xml:20903
15158 msgid "--use-post-commit-hook"
15162 #: ../source/book.xml:20906
15163 msgid "When loading a dump file, run the repository's post-commit hook after finalizing each newly loaded revision."
15167 #: ../source/book.xml:20913
15168 msgid "--use-pre-commit-hook"
15172 #: ../source/book.xml:20916
15173 msgid "When loading a dump file, run the repository's pre-commit hook before finalizing each newly loaded revision. If the hook fails, abort the commit and terminate the load process."
15177 #: ../source/book.xml:20927
15178 msgid "<command>svnadmin</command> Subcommands"
15182 #: ../source/book.xml:20933
15187 #: ../source/book.xml:20936
15188 msgid "svnadmin create"
15192 #: ../source/book.xml:20937
15193 msgid "Create a new, empty repository."
15197 #: ../source/book.xml:20943
15199 msgid "svnadmin create REPOS_PATH"
15203 #: ../source/book.xml:20951
15204 msgid "Remember, <command>svnadmin</command> works only with local <emphasis>paths</emphasis>, not <emphasis>URLs</emphasis>."
15208 #: ../source/book.xml:20949
15209 msgid "Create a new, empty repository at the path provided. If the provided directory does not exist, it will be created for you.<placeholder-1/> As of Subversion 1.2, <command>svnadmin</command> creates new repositories with the <literal>fsfs</literal> filesystem backend by default."
15213 #: ../source/book.xml:20963
15215 msgid "\n--bdb-txn-nosync\n--bdb-log-keep\n--config-dir DIR\n--fs-type TYPE\n"
15219 #: ../source/book.xml:20974
15220 msgid "Creating a new repository is just this easy:"
15224 #: ../source/book.xml:20975
15226 msgid "\n$ svnadmin create /usr/local/svn/repos\n"
15230 #: ../source/book.xml:20978
15231 msgid "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 <option>--fs-type</option> option:"
15235 #: ../source/book.xml:20983
15237 msgid "\n$ svnadmin create /usr/local/svn/repos --fs-type fsfs\n"
15241 #: ../source/book.xml:20992
15246 #: ../source/book.xml:20995
15247 msgid "svnadmin deltify"
15251 #: ../source/book.xml:20996
15252 msgid "Deltify changed paths in a revision range."
15256 #: ../source/book.xml:21002
15258 msgid "svnadmin deltify [-r LOWER[:UPPER]] REPOS_PATH"
15262 #: ../source/book.xml:21008
15263 msgid "<command>svnadmin deltify</command> exists in current versions of Subversion only for historical reasons. This command is deprecated and no longer needed."
15267 #: ../source/book.xml:21011
15268 msgid "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 <emphasis>very</emphasis> little gain, and this <quote>feature</quote> was deprecated."
15272 #: ../source/book.xml:21021
15274 msgid "\n--revision (-r) REV\n--quiet (-q)\n"
15278 #: ../source/book.xml:21031
15283 #: ../source/book.xml:21034
15284 msgid "svnadmin dump"
15288 #: ../source/book.xml:21035
15289 msgid "Dump the contents of filesystem to stdout."
15293 #: ../source/book.xml:21041
15295 msgid "svnadmin dump REPOS_PATH [-r LOWER[:UPPER]] [--incremental]"
15299 #: ../source/book.xml:21047
15300 msgid "Dump the contents of filesystem to stdout in a <quote>dumpfile</quote> portable format, sending feedback to stderr. Dump revisions <replaceable>LOWER</replaceable> rev through <replaceable>UPPER</replaceable> rev. If no revisions are given, dump all revision trees. If only <replaceable>LOWER</replaceable> is given, dump that one revision tree. See <xref linkend=\"svn.reposadmin.maint.migrate\"/> for a practical use."
15304 #: ../source/book.xml:21056
15305 msgid "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."
15309 #: ../source/book.xml:21067
15310 msgid "There are two useful options which modify the dumpfile generator's behavior. The first is the <option>--incremental</option> 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 relatively small dumpfile to be loaded into another repository which already has the files and directories that exist in the original repository."
15314 #: ../source/book.xml:21078
15315 msgid "The second useful option is <option>--deltas</option>. This option causes <command>svnadmin dump</command> 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 <command>svnadmin dump</command> creates. There are, however, disadvantages to using this option—deltified dumpfiles are more CPU intensive to create, cannot be operated on by <command>svndumpfilter</command>, and tend not to compress as well as their non-deltified counterparts when using third-party tools like <command>gzip</command> and <command>bzip2</command>."
15319 #: ../source/book.xml:21096
15321 msgid "\n--revision (-r) REV\n--incremental\n--quiet (-q)\n--deltas\n"
15325 #: ../source/book.xml:21107
15326 msgid "Dump your whole repository:"
15330 #: ../source/book.xml:21108
15332 msgid "\n$ svnadmin dump /usr/local/svn/repos\nSVN-fs-dump-format-version: 1\nRevision-number: 0\n* Dumped revision 0.\nProp-content-length: 56\nContent-length: 56\n…\n"
15336 #: ../source/book.xml:21117
15337 msgid "Incrementally dump a single transaction from your repository:"
15341 #: ../source/book.xml:21119
15343 msgid "\n$ svnadmin dump /usr/local/svn/repos -r 21 --incremental \n* Dumped revision 21.\nSVN-fs-dump-format-version: 1\nRevision-number: 21\nProp-content-length: 101\nContent-length: 101\n…\n"
15347 #: ../source/book.xml:21137
15348 msgid "svnadmin help"
15352 #: ../source/book.xml:21144
15354 msgid "svnadmin help [SUBCOMMAND...]"
15358 #: ../source/book.xml:21150
15359 msgid "This subcommand is useful when you're trapped on a desert island with neither a net connection nor a copy of this book."
15363 #: ../source/book.xml:21167
15368 #: ../source/book.xml:21170
15369 msgid "svnadmin hotcopy"
15373 #: ../source/book.xml:21171
15374 msgid "Make a hot copy of a repository."
15378 #: ../source/book.xml:21177
15380 msgid "svnadmin hotcopy REPOS_PATH NEW_REPOS_PATH"
15384 #: ../source/book.xml:21183
15385 msgid "This subcommand makes a full <quote>hot</quote> backup of your repository, including all hooks, configuration files, and, of course, database files. If you pass the <option>--clean-logs</option> option, <command>svnadmin</command> 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."
15389 #: ../source/book.xml:21197
15391 msgid "\n--clean-logs\n"
15395 #: ../source/book.xml:21201
15396 msgid "As described in <xref linkend=\"svn.reposadmin.basics.backends.bdb\"/>, hot-copied Berkeley DB repositories are <emphasis>not</emphasis> portable across operating systems, nor will they work on machines with a different <quote>endianness</quote> than the machine where they were created."
15400 #: ../source/book.xml:21213
15401 msgid "list-dblogs"
15405 #: ../source/book.xml:21216
15406 msgid "svnadmin list-dblogs"
15410 #: ../source/book.xml:21220 ../source/book.xml:21251 ../source/book.xml:21444
15415 #: ../source/book.xml:21217
15416 msgid "Ask Berkeley DB which log files exist for a given Subversion repository (applies only to repositories using the <placeholder-1/> backend)."
15420 #: ../source/book.xml:21226
15422 msgid "svnadmin list-dblogs REPOS_PATH"
15426 #: ../source/book.xml:21232 ../source/book.xml:21263
15427 msgid "Berkeley DB creates logs of all changes to the repository, which allow it to recover in the face of catastrophe. Unless you enable <literal>DB_LOG_AUTOREMOVE</literal>, the log files accumulate, although most are no longer used and can be deleted to reclaim disk space. See <xref linkend=\"svn.reposadmin.maint.diskspace\"/> for more information."
15431 #: ../source/book.xml:21245
15432 msgid "list-unused-dblogs"
15436 #: ../source/book.xml:21248
15437 msgid "svnadmin list-unused-dblogs"
15441 #: ../source/book.xml:21249
15442 msgid "Ask Berkeley DB which log files can be safely deleted (applies only to repositories using the <placeholder-1/> backend)."
15446 #: ../source/book.xml:21257
15448 msgid "svnadmin list-unused-dblogs REPOS_PATH"
15452 #: ../source/book.xml:21275
15453 msgid "Remove all unused log files from a repository:"
15457 #: ../source/book.xml:21276
15459 msgid "\n$ svnadmin list-unused-dblogs /path/to/repos\n/path/to/repos/log.0000000031\n/path/to/repos/log.0000000032\n/path/to/repos/log.0000000033\n\n$ svnadmin list-unused-dblogs /path/to/repos | xargs rm\n## disk space reclaimed!\n"
15463 #: ../source/book.xml:21291
15468 #: ../source/book.xml:21294
15469 msgid "svnadmin load"
15473 #: ../source/book.xml:21296
15478 #: ../source/book.xml:21295
15479 msgid "Read a <placeholder-1/>-formatted stream from stdin."
15483 #: ../source/book.xml:21303
15485 msgid "svnadmin load REPOS_PATH"
15489 #: ../source/book.xml:21309
15490 msgid "Read a <quote>dumpfile</quote>-formatted stream from stdin, committing new revisions into the repository's filesystem. Send progress feedback to stdout."
15494 #: ../source/book.xml:21317
15496 msgid "\n--quiet (-q)\n--ignore-uuid\n--force-uuid\n--use-pre-commit-hook\n--use-post-commit-hook\n--parent-dir\n"
15500 #: ../source/book.xml:21328 ../source/book.xml:21380 ../source/book.xml:21542
15505 #: ../source/book.xml:21330
15506 msgid "This shows the beginning of loading a repository from a backup file (made, of course, with <command>svnadmin dump</command>):"
15510 #: ../source/book.xml:21333
15512 msgid "\n$ svnadmin load /usr/local/svn/restored < repos-backup\n<<< Started new txn, based on original revision 1\n * adding path : test ... done.\n * adding path : test/a ... done.\n…\n"
15516 #: ../source/book.xml:21340
15517 msgid "Or if you want to load into a subdirectory:"
15521 #: ../source/book.xml:21341
15523 msgid "\n$ svnadmin load --parent-dir new/subdir/for/project /usr/local/svn/restored < repos-backup\n<<< Started new txn, based on original revision 1\n * adding path : test ... done.\n * adding path : test/a ... done.\n…\n"
15527 #: ../source/book.xml:21354
15532 #: ../source/book.xml:21357
15533 msgid "svnadmin lslocks"
15537 #: ../source/book.xml:21358
15538 msgid "Print descriptions of all locks."
15542 #: ../source/book.xml:21364
15544 msgid "svnadmin lslocks REPOS_PATH"
15548 #: ../source/book.xml:21370
15549 msgid "Print descriptions of all locks in a repository."
15553 #: ../source/book.xml:21382
15554 msgid "This lists the one locked file in the repository at <filename>/svn/repos</filename>:"
15558 #: ../source/book.xml:21384
15560 msgid "\n$ svnadmin lslocks /svn/repos\nPath: /tree.jpg\nUUID Token: opaquelocktoken:ab00ddf0-6afb-0310-9cd0-dda813329753\nOwner: harry\nCreated: 2005-07-08 17:27:36 -0500 (Fri, 08 Jul 2005)\nExpires: \nComment (1 line):\nRework the uppermost branches on the bald cypress in the foreground.\n"
15564 #: ../source/book.xml:21400
15569 #: ../source/book.xml:21403
15570 msgid "svnadmin lstxns"
15574 #: ../source/book.xml:21404
15575 msgid "Print the names of all uncommitted transactions."
15579 #: ../source/book.xml:21410
15581 msgid "svnadmin lstxns REPOS_PATH"
15585 #: ../source/book.xml:21416
15586 msgid "Print the names of all uncommitted transactions. See <xref linkend=\"svn.reposadmin.maint.diskspace.deadtxns\"/> for information on how uncommitted transactions are created and what you should do with them."
15590 #: ../source/book.xml:21425
15591 msgid "List all outstanding transactions in a repository."
15595 #: ../source/book.xml:21427
15597 msgid "\n$ svnadmin lstxns /usr/local/svn/repos/ \n1w\n1x\n"
15601 #: ../source/book.xml:21438
15606 #: ../source/book.xml:21441
15607 msgid "svnadmin recover"
15611 #: ../source/book.xml:21445
15612 msgid "repos/conf/passwd"
15616 #: ../source/book.xml:21442
15617 msgid "Bring a repository database back into a consistent state (applies only to repositories using the <placeholder-1/> backend). In addition, if <placeholder-2/> does not exist, it will create a default password file ."
15621 #: ../source/book.xml:21452
15623 msgid "svnadmin recover REPOS_PATH"
15627 #: ../source/book.xml:21458
15628 msgid "Run this command if you get an error indicating that your repository needs to be recovered."
15632 #: ../source/book.xml:21465
15638 #: ../source/book.xml:21473
15639 msgid "Recover a hung repository:"
15643 #: ../source/book.xml:21474
15645 msgid "\n$ svnadmin recover /usr/local/svn/repos/ \nRepository lock acquired.\nPlease wait; recovering the repository may take some time...\n\nRecovery completed.\nThe latest repos revision is 34.\n"
15649 #: ../source/book.xml:21482
15650 msgid "Recovering the database requires an exclusive lock on the repository. (This is a <quote>database lock</quote>; see <xref linkend=\"svn.advanced.locking.meanings\"/>.) If another process is accessing the repository, then <command>svnadmin recover</command> will error:"
15654 #: ../source/book.xml:21487
15656 msgid "\n$ svnadmin recover /usr/local/svn/repos\nsvn: Failed to get exclusive repository access; perhaps another process\nsuch as httpd, svnserve or svn has it open?\n\n$\n"
15660 #: ../source/book.xml:21494
15661 msgid "The <option>--wait</option> option, however, will cause <command>svnadmin recover</command> to wait indefinitely for other processes to disconnect:"
15665 #: ../source/book.xml:21497
15667 msgid "\n$ svnadmin recover /usr/local/svn/repos --wait\nWaiting on repository lock; perhaps another process has it open?\n\n### time goes by…\n\nRepository lock acquired.\nPlease wait; recovering the repository may take some time...\n\nRecovery completed.\nThe latest repos revision is 34.\n"
15671 #: ../source/book.xml:21515
15676 #: ../source/book.xml:21518
15677 msgid "svnadmin rmlocks"
15681 #: ../source/book.xml:21519
15682 msgid "Unconditionally remove one or more locks from a repository."
15686 #: ../source/book.xml:21526
15688 msgid "svnadmin rmlocks REPOS_PATH LOCKED_PATH..."
15692 #: ../source/book.xml:21532
15693 msgid "Remove lock from each <replaceable>LOCKED_PATH</replaceable>."
15697 #: ../source/book.xml:21544
15698 msgid "This deletes the locks on <filename>tree.jpg</filename> and <filename>house.jpg</filename> in the repository at <filename>/svn/repos</filename>"
15702 #: ../source/book.xml:21548
15704 msgid "\n$ svnadmin rmlocks /svn/repos tree.jpg house.jpg\nRemoved lock on '/tree.jpg.\nRemoved lock on '/house.jpg.\n"
15708 #: ../source/book.xml:21559
15713 #: ../source/book.xml:21562
15714 msgid "svnadmin rmtxns"
15718 #: ../source/book.xml:21563
15719 msgid "Delete transactions from a repository."
15723 #: ../source/book.xml:21569
15725 msgid "svnadmin rmtxns REPOS_PATH TXN_NAME..."
15729 #: ../source/book.xml:21575
15730 msgid "Delete outstanding transactions from a repository. This is covered in detail in <xref linkend=\"svn.reposadmin.maint.diskspace.deadtxns\"/>."
15734 #: ../source/book.xml:21582
15736 msgid "\n--quiet (-q)\n"
15740 #: ../source/book.xml:21590
15741 msgid "Remove named transactions:"
15745 #: ../source/book.xml:21591
15747 msgid "\n$ svnadmin rmtxns /usr/local/svn/repos/ 1w 1x\n"
15751 #: ../source/book.xml:21594
15752 msgid "Fortunately, the output of <command>lstxns</command> works great as the input for <command>rmtxns</command>:"
15756 #: ../source/book.xml:21596
15758 msgid "\n$ svnadmin rmtxns /usr/local/svn/repos/ `svnadmin lstxns /usr/local/svn/repos/`\n"
15762 #: ../source/book.xml:21599
15763 msgid "Which will remove all uncommitted transactions from your repository."
15767 #: ../source/book.xml:21607
15772 #: ../source/book.xml:21610
15773 msgid "svnadmin setlog"
15777 #: ../source/book.xml:21611
15778 msgid "Set the log-message on a revision."
15782 #: ../source/book.xml:21617
15784 msgid "svnadmin setlog REPOS_PATH -r REVISION FILE"
15788 #: ../source/book.xml:21623
15789 msgid "Set the log-message on revision REVISION to the contents of FILE."
15793 #: ../source/book.xml:21625
15794 msgid "This is similar to using <command>svn propset --revprop</command> to set the <literal>svn:log</literal> property on a revision, except that you can also use the option <option>--bypass-hooks</option> 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."
15798 #: ../source/book.xml:21633
15799 msgid "Revision properties are not under version control, so this command will permanently overwrite the previous log message."
15803 #: ../source/book.xml:21642
15805 msgid "\n--revision (-r) REV\n--bypass-hooks\n"
15809 #: ../source/book.xml:21651
15810 msgid "Set the log message for revision 19 to the contents of the file <filename>msg</filename>:"
15814 #: ../source/book.xml:21653
15816 msgid "\n$ svnadmin setlog /usr/local/svn/repos/ -r 19 msg\n"
15820 #: ../source/book.xml:21664
15825 #: ../source/book.xml:21667
15826 msgid "svnadmin verify"
15830 #: ../source/book.xml:21668
15831 msgid "Verify the data stored in the repository."
15835 #: ../source/book.xml:21674
15837 msgid "svnadmin verify REPOS_PATH"
15841 #: ../source/book.xml:21680
15842 msgid "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—it's a good idea to run this on a regular basis to guard against latent hard disk failures and <quote>bitrot</quote>. If this command fails—which it will do at the first sign of a problem—that means that your repository has at least one corrupted revision and you should restore the corrupted revision from a backup (you did make a backup, didn't you?)."
15846 #: ../source/book.xml:21696
15847 msgid "Verify a hung repository:"
15851 #: ../source/book.xml:21697
15853 msgid "\n$ svnadmin verify /usr/local/svn/repos/ \n* Verified revision 1729.\n"
15857 #: ../source/book.xml:21714
15858 msgid "<command>svnlook</command> is a command-line utility for examining different aspects of a Subversion repository. It does not make any changes to the repository—it's just used for <quote>peeking</quote>. <command>svnlook</command> is typically used by the repository hooks, but a repository administrator might find it useful for diagnostic purposes."
15862 #: ../source/book.xml:21721
15863 msgid "Since <command>svnlook</command> works via direct repository access (and thus can only be used on the machine that holds the repository), it refers to the repository with a path, not a URL."
15867 #: ../source/book.xml:21724
15868 msgid "If no revision or transaction is specified, <command>svnlook</command> defaults to the youngest (most recent) revision of the repository."
15872 #: ../source/book.xml:21730
15873 msgid "<command>svnlook</command> Options"
15877 #: ../source/book.xml:21732
15878 msgid "Options in <command>svnlook</command> are global, just like in <command>svn</command> and <command>svnadmin</command>; however, most options only apply to one subcommand since the functionality of <command>svnlook</command> is (intentionally) limited in scope."
15882 #: ../source/book.xml:21744
15883 msgid "Prevents <command>svnlook diff</command> from printing differences for deleted files. The default behavior when a file is deleted in a transaction/revision is to print the same differences that you would see if you had left the file but removed all the content."
15887 #: ../source/book.xml:21753
15888 msgid "--no-diff-added"
15892 #: ../source/book.xml:21756
15893 msgid "Prevents <command>svnlook diff</command> from printing differences for added files. The default behavior when you add a file is to print the same differences that you would see if you had added the entire contents of an existing (empty) file."
15897 #: ../source/book.xml:21764
15898 msgid "<option>--revision</option> (<option>-r</option>)"
15902 #: ../source/book.xml:21767
15903 msgid "Specify a particular revision number that you wish to examine."
15907 #: ../source/book.xml:21784
15908 msgid "<option>--transaction</option> (<option>-t</option>)"
15912 #: ../source/book.xml:21787
15913 msgid "Specify a particular transaction ID that you wish to examine."
15917 #: ../source/book.xml:21793
15922 #: ../source/book.xml:21796
15923 msgid "Show the filesystem node revision IDs for each path in the filesystem tree."
15927 #: ../source/book.xml:21805
15928 msgid "<command>svnlook</command> Subcommands"
15932 #: ../source/book.xml:21811
15937 #: ../source/book.xml:21814
15938 msgid "svnlook author"
15942 #: ../source/book.xml:21815
15943 msgid "Print the author."
15947 #: ../source/book.xml:21821
15949 msgid "svnlook author REPOS_PATH"
15953 #: ../source/book.xml:21827
15954 msgid "Print the author of a revision or transaction in the repository."
15958 #: ../source/book.xml:21834 ../source/book.xml:21877 ../source/book.xml:21970 ../source/book.xml:22023 ../source/book.xml:22137 ../source/book.xml:22277 ../source/book.xml:22373
15960 msgid "\n--revision (-r) REV\n--transaction (-t)\n"
15964 #: ../source/book.xml:21843
15965 msgid "<command>svnlook author</command> is handy, but not very exciting:"
15969 #: ../source/book.xml:21845
15971 msgid "\n$ svnlook author -r 40 /usr/local/svn/repos \nsally\n"
15975 #: ../source/book.xml:21858
15976 msgid "svnlook cat"
15979 #.(refpurpose), (para)
15980 #: ../source/book.xml:21859 ../source/book.xml:21871
15981 msgid "Print the contents of a file."
15985 #: ../source/book.xml:21865
15987 msgid "svnlook cat REPOS_PATH PATH_IN_REPOS"
15991 #: ../source/book.xml:21886
15992 msgid "This shows the contents of a file in transaction <literal>ax8</literal>, located at <filename>/trunk/README</filename>:"
15996 #: ../source/book.xml:21889
15998 msgid "\n$ svnlook cat -t ax8 /usr/local/svn/repos /trunk/README\n\n Subversion, a version control system.\n =====================================\n\n$LastChangedDate: 2003-07-17 10:45:25 -0500 (Thu, 17 Jul 2003) $\n\nContents:\n\n I. A FEW POINTERS\n II. DOCUMENTATION\n III. PARTICIPATING IN THE SUBVERSION COMMUNITY\n…\n"
16002 #: ../source/book.xml:21910
16007 #: ../source/book.xml:21913
16008 msgid "svnlook changed"
16012 #: ../source/book.xml:21914
16013 msgid "Print the paths that were changed."
16017 #: ../source/book.xml:21920
16019 msgid "svnlook changed REPOS_PATH"
16023 #: ../source/book.xml:21926
16024 msgid "Print the paths that were changed in a particular revision or transaction, as well as <quote>svn update-style</quote> status letters in the first two columns:"
16028 #: ../source/book.xml:21932
16029 msgid "'<literal>A </literal>'"
16033 #: ../source/book.xml:21934
16034 msgid "Item added to repository."
16038 #: ../source/book.xml:21938
16039 msgid "'<literal>D </literal>'"
16043 #: ../source/book.xml:21940
16044 msgid "Item deleted from repository."
16048 #: ../source/book.xml:21944
16049 msgid "'<literal>U </literal>'"
16053 #: ../source/book.xml:21946
16054 msgid "File contents changed."
16058 #: ../source/book.xml:21950
16059 msgid "'<literal> U</literal>'"
16063 #: ../source/book.xml:21952
16064 msgid "Properties of item changed. Note the leading space."
16068 #: ../source/book.xml:21956
16069 msgid "'<literal>UU</literal>'"
16073 #: ../source/book.xml:21958
16074 msgid "File contents and properties changed."
16078 #: ../source/book.xml:21962
16079 msgid "Files and directories can be distinguished, as directory paths are displayed with a trailing '<literal>/</literal>' character."
16083 #: ../source/book.xml:21979
16084 msgid "This shows a list of all the changed files and directories in revision 39 of a test repository. Note that the first changed item is a directory, as evidenced by the trailing <literal>/</literal>:"
16088 #: ../source/book.xml:21983
16090 msgid "\n$ svnlook changed -r 39 /usr/local/svn/repos\nA trunk/vendors/deli/\nA trunk/vendors/deli/chips.txt\nA trunk/vendors/deli/sandwich.txt\nA trunk/vendors/deli/pickle.txt\nU trunk/vendors/baker/bagel.txt\n U trunk/vendors/baker/croissant.txt\nUU trunk/vendors/baker/pretzel.txt\nD trunk/vendors/baker/baguette.txt\n"
16094 #: ../source/book.xml:22000
16099 #: ../source/book.xml:22003
16100 msgid "svnlook date"
16104 #: ../source/book.xml:22004
16105 msgid "Print the datestamp."
16109 #: ../source/book.xml:22010
16111 msgid "svnlook date REPOS_PATH"
16115 #: ../source/book.xml:22016
16116 msgid "Print the datestamp of a revision or transaction in a repository."
16120 #: ../source/book.xml:22032
16121 msgid "This shows the date of revision 40 of a test repository:"
16125 #: ../source/book.xml:22034
16127 msgid "\n$ svnlook date -r 40 /tmp/repos/\n2003-02-22 17:44:49 -0600 (Sat, 22 Feb 2003)\n"
16131 #: ../source/book.xml:22047
16132 msgid "svnlook diff"
16136 #: ../source/book.xml:22048
16137 msgid "Print differences of changed files and properties."
16141 #: ../source/book.xml:22054
16143 msgid "svnlook diff REPOS_PATH"
16147 #: ../source/book.xml:22060
16148 msgid "Print GNU-style differences of changed files and properties in a repository."
16152 #: ../source/book.xml:22067
16154 msgid "\n--revision (-r) REV\n--transaction (-t)\n--no-diff-added\n--no-diff-deleted\n"
16158 #: ../source/book.xml:22078
16159 msgid "This shows a newly added (empty) file, a deleted file, and a copied file:"
16163 #: ../source/book.xml:22080
16165 msgid "\n$ svnlook diff -r 40 /usr/local/svn/repos/\nCopied: egg.txt (from rev 39, trunk/vendors/deli/pickle.txt)\n\nAdded: trunk/vendors/deli/soda.txt\n==============================================================================\n\nModified: trunk/vendors/deli/sandwich.txt\n==============================================================================\n--- trunk/vendors/deli/sandwich.txt\t(original)\n+++ trunk/vendors/deli/sandwich.txt\t2003-02-22 17:45:04.000000000 -0600\n@@ -0,0 +1 @@\n+Don't forget the mayo!\n\nModified: trunk/vendors/deli/logo.jpg\n==============================================================================\n(Binary files differ)\n\nDeleted: trunk/vendors/deli/chips.txt\n==============================================================================\n\nDeleted: trunk/vendors/deli/pickle.txt\n==============================================================================\n"
16169 #: ../source/book.xml:22104
16170 msgid "If a file has a non-textual <literal>svn:mime-type</literal> property, then the differences are not explicitly shown."
16174 #: ../source/book.xml:22113
16175 msgid "dirs-changed"
16179 #: ../source/book.xml:22116
16180 msgid "svnlook dirs-changed"
16184 #: ../source/book.xml:22117
16185 msgid "Print the directories that were themselves changed."
16189 #: ../source/book.xml:22123
16191 msgid "svnlook dirs-changed REPOS_PATH"
16195 #: ../source/book.xml:22129
16196 msgid "Print the directories that were themselves changed (property edits) or whose file children were changed."
16200 #: ../source/book.xml:22146
16201 msgid "This shows the directories that changed in revision 40 in our sample repository:"
16205 #: ../source/book.xml:22148
16207 msgid "\n$ svnlook dirs-changed -r 40 /usr/local/svn/repos\ntrunk/vendors/deli/\n"
16211 #: ../source/book.xml:22161
16212 msgid "svnlook help"
16216 #: ../source/book.xml:22168
16218 msgid "Also svnlook -h and svnlook -?."
16222 #: ../source/book.xml:22174
16223 msgid "Displays the help message for svnlook. This command, like its brother <command>svn help</command>, is also your friend, even though you never call it anymore and forgot to invite it to your last party."
16227 #: ../source/book.xml:22190
16232 #: ../source/book.xml:22193
16233 msgid "svnlook history"
16236 #.(refpurpose), (para)
16237 #: ../source/book.xml:22194 ../source/book.xml:22208
16238 msgid "Print information about the history of a path in the repository (or the root directory if no path is supplied)."
16242 #: ../source/book.xml:22202
16244 msgid "svnlook history REPOS_PATH [PATH_IN_REPOS]"
16248 #: ../source/book.xml:22216
16250 msgid "\n--revision (-r) REV\n--show-ids\n"
16254 #: ../source/book.xml:22225
16255 msgid "This shows the history output for the path <filename>/tags/1.0</filename> as of revision 20 in our sample repository."
16259 #: ../source/book.xml:22228
16261 msgid "\n$ svnlook history -r 20 /usr/local/svn/repos /tags/1.0 --show-ids\nREVISION PATH <ID>\n-------- ---------\n 19 /tags/1.0 <1.2.12>\n 17 /branches/1.0-rc2 <1.1.10>\n 16 /branches/1.0-rc2 <1.1.x>\n 14 /trunk <1.0.q>\n 13 /trunk <1.0.o>\n 11 /trunk <1.0.k>\n 9 /trunk <1.0.g>\n 8 /trunk <1.0.e>\n 7 /trunk <1.0.b>\n 6 /trunk <1.0.9>\n 5 /trunk <1.0.7>\n 4 /trunk <1.0.6>\n 2 /trunk <1.0.3>\n 1 /trunk <1.0.2>\n"
16265 #: ../source/book.xml:22256
16266 msgid "svnlook info"
16270 #: ../source/book.xml:22257
16271 msgid "Print the author, datestamp, log message size, and log message."
16275 #: ../source/book.xml:22264
16277 msgid "svnlook info REPOS_PATH"
16281 #: ../source/book.xml:22270
16282 msgid "Print the author, datestamp, log message size (in bytes) and log message, followed by a newline character."
16286 #: ../source/book.xml:22286
16287 msgid "This shows the info output for revision 40 in our sample repository."
16291 #: ../source/book.xml:22288
16293 msgid "\n$ svnlook info -r 40 /usr/local/svn/repos\nsally\n2003-02-22 17:44:49 -0600 (Sat, 22 Feb 2003)\n16\nRearrange lunch.\n"
16297 #: ../source/book.xml:22304
16298 msgid "svnlook lock"
16302 #: ../source/book.xml:22305
16303 msgid "If a lock exists on a path in the repository, describe it."
16307 #: ../source/book.xml:22312
16309 msgid "svnlook lock REPOS_PATH PATH_IN_REPOS"
16313 #: ../source/book.xml:22318
16314 msgid "Print all information available for the lock at <replaceable>PATH_IN_REPOS</replaceable>. If <replaceable>PATH_IN_REPOS</replaceable> is not locked, print nothing."
16318 #: ../source/book.xml:22333
16319 msgid "This describes the lock on the file <filename>tree.jpg</filename>."
16323 #: ../source/book.xml:22335
16325 msgid "\n$ svnlook lock /svn/repos tree.jpg\nUUID Token: opaquelocktoken:ab00ddf0-6afb-0310-9cd0-dda813329753\nOwner: harry\nCreated: 2005-07-08 17:27:36 -0500 (Fri, 08 Jul 2005)\nExpires: \nComment (1 line):\nRework the uppermost branches on the bald cypress in the foreground.\n"
16329 #: ../source/book.xml:22353
16330 msgid "svnlook log"
16334 #: ../source/book.xml:22354
16335 msgid "Print the log message, followed by a newline character."
16339 #: ../source/book.xml:22361
16341 msgid "svnlook log REPOS_PATH"
16345 #: ../source/book.xml:22367
16346 msgid "Print the log message."
16350 #: ../source/book.xml:22382
16351 msgid "This shows the log output for revision 40 in our sample repository:"
16355 #: ../source/book.xml:22384
16357 msgid "\n$ svnlook log /tmp/repos/\nRearrange lunch.\n"
16361 #: ../source/book.xml:22397
16362 msgid "svnlook propget"
16366 #: ../source/book.xml:22398
16367 msgid "Print the raw value of a property on a path in the repository."
16371 #: ../source/book.xml:22405
16373 msgid "svnlook propget REPOS_PATH PROPNAME [PATH_IN_REPOS]"
16377 #: ../source/book.xml:22411
16378 msgid "List the value of a property on a path in the repository."
16382 #: ../source/book.xml:22418
16387 #: ../source/book.xml:22424
16389 msgid "\n--revision (-r) REV\n--transaction (-t)\n--revprop\n"
16393 #: ../source/book.xml:22434
16394 msgid "This shows the value of the <quote>seasonings</quote> property on the file <filename>/trunk/sandwich</filename> in the <literal>HEAD</literal> revision:"
16398 #: ../source/book.xml:22437
16400 msgid "\n$ svnlook pg /usr/local/svn/repos seasonings /trunk/sandwich\nmustard\n"
16404 #: ../source/book.xml:22450
16405 msgid "svnlook proplist"
16409 #: ../source/book.xml:22451
16410 msgid "Print the names and values of versioned file and directory properties."
16414 #: ../source/book.xml:22458
16416 msgid "svnlook proplist REPOS_PATH [PATH_IN_REPOS]"
16420 #: ../source/book.xml:22464
16421 msgid "List the properties of a path in the repository. With <option>--verbose</option>, show the property values too."
16425 #: ../source/book.xml:22471
16430 #: ../source/book.xml:22477
16432 msgid "\n--revision (-r) REV\n--transaction (-t)\n--verbose (-v)\n--revprop\n"
16436 #: ../source/book.xml:22488
16437 msgid "This shows the names of properties set on the file <filename>/trunk/README</filename> in the <literal>HEAD</literal> revision:"
16441 #: ../source/book.xml:22491
16443 msgid "\n$ svnlook proplist /usr/local/svn/repos /trunk/README\n original-author\n svn:mime-type\n"
16447 #: ../source/book.xml:22496
16448 msgid "This is the same command as in the previous example, but this time showing the property values as well:"
16452 #: ../source/book.xml:22498
16454 msgid "\n$ svnlook --verbose proplist /usr/local/svn/repos /trunk/README\n original-author : fitz\n svn:mime-type : text/plain\n"
16458 #: ../source/book.xml:22509
16463 #: ../source/book.xml:22512
16464 msgid "svnlook tree"
16468 #: ../source/book.xml:22513
16469 msgid "Print the tree."
16473 #: ../source/book.xml:22519
16475 msgid "svnlook tree REPOS_PATH [PATH_IN_REPOS]"
16479 #: ../source/book.xml:22525
16480 msgid "Print the tree, starting at <replaceable>PATH_IN_REPOS</replaceable> (if supplied, at the root of the tree otherwise), optionally showing node revision IDs."
16484 #: ../source/book.xml:22534
16486 msgid "\n--revision (-r) REV\n--transaction (-t)\n--show-ids\n"
16490 #: ../source/book.xml:22544
16491 msgid "This shows the tree output (with node-IDs) for revision 40 in our sample repository:"
16495 #: ../source/book.xml:22546
16497 msgid "\n$ svnlook tree -r 40 /usr/local/svn/repos --show-ids\n/ <0.0.2j>\n trunk/ <p.0.2j>\n vendors/ <q.0.2j>\n deli/ <1g.0.2j>\n egg.txt <1i.e.2j>\n soda.txt <1k.0.2j>\n sandwich.txt <1j.0.2j>\n"
16501 #: ../source/book.xml:22562
16506 #: ../source/book.xml:22565
16507 msgid "svnlook uuid"
16511 #: ../source/book.xml:22567
16516 #: ../source/book.xml:22566
16517 msgid "Print the repository's <placeholder-1/>."
16521 #: ../source/book.xml:22573
16523 msgid "svnlook uuid REPOS_PATH"
16527 #: ../source/book.xml:22579
16528 msgid "Print the <literal>UUID</literal> for the repository. the UUID is the repository's <emphasis>u</emphasis>niversal <emphasis>u</emphasis>nique <emphasis>id</emphasis>entifier. The Subversion client uses this identifier to differentiate between one repository and another."
16532 #: ../source/book.xml:22590
16534 msgid "\n$ svnlook uuid /usr/local/svn/repos\ne7fe1b91-8cd5-0310-98dd-2f12e793c5e8\n"
16538 #: ../source/book.xml:22600
16543 #: ../source/book.xml:22603
16544 msgid "svnlook youngest"
16548 #: ../source/book.xml:22604
16549 msgid "Print the youngest revision number."
16553 #: ../source/book.xml:22610
16555 msgid "svnlook youngest REPOS_PATH"
16559 #: ../source/book.xml:22616
16560 msgid "Print the youngest revision number of a repository."
16564 #: ../source/book.xml:22622
16565 msgid "This shows the youngest revision of our sample repository:"
16569 #: ../source/book.xml:22624
16571 msgid "\n$ svnlook youngest /tmp/repos/ \n42\n"
16575 #: ../source/book.xml:22641
16576 msgid "<command>svnsync</command> is the Subversion remote repository mirroring tool. Put simply, it allows you to replay the revisions of one repository into another one."
16580 #: ../source/book.xml:22644
16581 msgid "In any mirroring scenario, there are two repositories: the source repository, and the mirror (or <quote>sink</quote>) repository. The source repository is the repository from which <command>svnsync</command> pulls revisions. The mirror repository is the destination for the revisions pulled from the source repository. Each of the repositories may be local or remote—they are only ever addressed by their URLs."
16585 #: ../source/book.xml:22651
16586 msgid "The <command>svnsync</command> process requires only read access to the source repository; it never attempts to modify it. But obviously, <command>svnsync</command> requires both read and write access to the mirror repository."
16590 #: ../source/book.xml:22656
16591 msgid "<command>svnsync</command> is very sensitive to changes made in the mirror repository that weren't made as part of a mirroring operation. To prevent this from happening, it's best if the <command>svnsync</command> process is the only process permitted to modify the mirror repository."
16595 #: ../source/book.xml:22665
16596 msgid "<command>svnsync</command> Options"
16600 #: ../source/book.xml:22732
16601 msgid "<command>svnsync</command> Subcommands"
16605 #: ../source/book.xml:22739
16606 msgid "copy-revprops"
16610 #: ../source/book.xml:22742
16611 msgid "svnsync copy-revprops"
16615 #: ../source/book.xml:22743
16616 msgid "Copy all revision properties for a given revision from the source repository to the mirror repository."
16620 #: ../source/book.xml:22751
16622 msgid "svnsync copy-revprops DEST_URL REV"
16626 #: ../source/book.xml:22757
16627 msgid "Because Subversion revision properties can be changed at any time, it's possible that the properties for some revision might be changed after that revision has already been synchronized to another repository. Because the <command>svnsync synchronize</command> command operates only on the range of revisions that have not yet been synchronized, it won't notice a revision property change outside that range. Left as is, this causes a deviation in the values of that revision's properties between the source and mirror repositories. <command>svnsync copy-revprops</command> is the answer to this problem. Use it to re-synchronize the revision properties for a particular revision."
16631 #: ../source/book.xml:22781 ../source/book.xml:22842 ../source/book.xml:22912
16633 msgid "\n--non-interactive\n--no-auth-cache\n--username NAME\n--password PASS\n--config-dir DIR\n"
16637 #: ../source/book.xml:22793
16638 msgid "Re-synchronize revision properties for a single revision:"
16642 #: ../source/book.xml:22794
16644 msgid "\n$ svnsync copy-revprops file:///opt/svn/repos-mirror 6\nCopied properties for revision 6.\n$\n"
16648 #: ../source/book.xml:22805
16653 #: ../source/book.xml:22808
16654 msgid "svnsync initialize"
16658 #: ../source/book.xml:22809
16659 msgid "Initialize a destination repository for synchronization from another repository."
16663 #: ../source/book.xml:22816
16665 msgid "svnsync initialize DEST_URL SOURCE_URL"
16669 #: ../source/book.xml:22822
16670 msgid "<command>svnsync initialize</command> verifies that a repository meets the requirements of a new mirror repository—that it has no previous existing version history, and that it allows revision property modifications—and records the initial administrative information which associates the mirror repository with the source repository. This is the first <command>svnsync</command> operation you run on a would-be mirror repository."
16674 #: ../source/book.xml:22836
16679 #: ../source/book.xml:22854
16680 msgid "Fail to initialize a mirror repository due to inability to modify revision properties:"
16684 #: ../source/book.xml:22856
16686 msgid "\n$ svnsync initialize file:///opt/svn/repos-mirror http://svn.example.com/repos\nsvnsync: Repository has not been enabled to accept revision propchanges;\nask the administrator to create a pre-revprop-change hook\n$\n"
16690 #: ../source/book.xml:22862
16691 msgid "Initialize a repository as a mirror, having already created a pre-revprop-change hook which permits all revision property changes:"
16695 #: ../source/book.xml:22865
16697 msgid "\n$ svnsync initialize file:///opt/svn/repos-mirror http://svn.example.com/repos\nCopied properties for revision 0.\n$\n"
16701 #: ../source/book.xml:22876
16702 msgid "synchronize"
16706 #: ../source/book.xml:22879
16707 msgid "svnsync synchronize"
16711 #: ../source/book.xml:22880
16712 msgid "Transfer all pending revisions from the source repository to the mirror repository."
16716 #: ../source/book.xml:22887
16718 msgid "svnsync synchronize DEST_URL"
16722 #: ../source/book.xml:22893
16723 msgid "The <command>svnsync synchronize</command> command does all the heavy lifting of a repository mirroring operation. After consulting with the mirror repository to see which revisions have already been copied into it, it then begins copying any not-yet-mirrored revisions from the source repository."
16727 #: ../source/book.xml:22899
16728 msgid "<command>svnsync synchronize</command> can be gracefully cancelled and restarted."
16732 #: ../source/book.xml:22906
16737 #: ../source/book.xml:22924
16738 msgid "Copy unsynchronized revisions from the source repository to the mirror repository:"
16742 #: ../source/book.xml:22926
16744 msgid "\n$ svnsync synchronize file:///opt/svn/repos-mirror\nCommitted revision 1.\nCopied properties for revision 1.\nCommitted revision 2.\nCopied properties for revision 2.\nCommitted revision 3.\nCopied properties for revision 3.\n…\nCommitted revision 45.\nCopied properties for revision 45.\nCommitted revision 46.\nCopied properties for revision 46.\nCommitted revision 47.\nCopied properties for revision 47.\n$\n"
16748 #: ../source/book.xml:22956
16749 msgid "<command>svnserve</command> allows access to Subversion repositories using Subversion's custom network protocol."
16753 #: ../source/book.xml:22958
16754 msgid "You can run <command>svnserve</command> as a standalone server process (for clients that are using the <literal>svn://</literal> access method); you can have a daemon such as <command>inetd</command> or <command>xinetd</command> launch it for you on demand (also for <literal>svn://</literal>), or you can have <command>sshd</command> launch it on demand for the <literal>svn+ssh://</literal> access method."
16758 #: ../source/book.xml:22966
16759 msgid "Regardless of the access method, once the client has selected a repository by transmitting its URL, <command>svnserve</command> reads a file named <filename>conf/svnserve.conf</filename> in the repository directory to determine repository-specific settings such as what authentication database to use and what authorization policies to apply. See <xref linkend=\"svn.serverconfig.svnserve\"/> for details of the <filename>svnserve.conf</filename> file."
16763 #: ../source/book.xml:22977
16764 msgid "<command>svnserve</command> Options"
16768 #: ../source/book.xml:22979
16769 msgid "Unlike the previous commands we've described, <command>svnserve</command> has no subcommands—<command>svnserve</command> is controlled exclusively by options."
16773 #: ../source/book.xml:22985
16774 msgid "<option>--daemon</option> (<option>-d</option>)"
16778 #: ../source/book.xml:22987
16779 msgid "Causes <command>svnserve</command> to run in daemon mode. <command>svnserve</command> backgrounds itself and accepts and serves TCP/IP connections on the svn port (3690, by default)."
16783 #: ../source/book.xml:22994
16784 msgid "<option>--listen-port</option>=<replaceable>PORT</replaceable>"
16788 #: ../source/book.xml:22996
16789 msgid "Causes svnserve to listen on <replaceable>PORT</replaceable> when run in daemon mode. (FreeBSD daemons only listen on tcp6 by default—this option tells them to also listen on tcp4.)"
16793 #: ../source/book.xml:23003
16794 msgid "<option>--listen-host</option>=<replaceable>HOST</replaceable>"
16798 #: ../source/book.xml:23005
16799 msgid "Causes <command>svnserve</command> to listen on the interface specified by <replaceable>HOST</replaceable>, which may be either a hostname or an IP address."
16803 #: ../source/book.xml:23012
16804 msgid "--foreground"
16808 #: ../source/book.xml:23015
16809 msgid "When used together with <option>-d</option>, this option causes <command>svnserve</command> to stay in the foreground. This option is mainly useful for debugging."
16813 #: ../source/book.xml:23022
16814 msgid "<option>--inetd</option> (<option>-i</option>)"
16818 #: ../source/book.xml:23024
16819 msgid "Causes <command>svnserve</command> to use the stdin/stdout file descriptors, as is appropriate for a daemon running out of <command>inetd</command>."
16823 #: ../source/book.xml:23030 ../source/book.xml:23177
16824 msgid "<option>--help</option> (<option>-h</option>)"
16828 #: ../source/book.xml:23032
16829 msgid "Displays a usage summary and exits."
16833 #: ../source/book.xml:23040
16834 msgid "Displays version information, a list of repository back-end modules available, and exits."
16838 #: ../source/book.xml:23045
16839 msgid "<option>--root</option>=<replaceable>ROOT</replaceable> (<option>-r</option>=<replaceable>ROOT</replaceable>)"
16843 #: ../source/book.xml:23048
16844 msgid "Sets the virtual root for repositories served by <command>svnserve</command>. The pathname in URLs provided by the client will be interpreted relative to this root, and will not be allowed to escape this root."
16848 #: ../source/book.xml:23056
16849 msgid "<option>--tunnel</option> (<option>-t</option>)"
16853 #: ../source/book.xml:23058
16854 msgid "Causes <command>svnserve</command> to run in tunnel mode, which is just like the <command>inetd</command> mode of operation (both modes serve one connection over stdin/stdout, then exit), except that the connection is considered to be pre-authenticated with the username of the current uid. This flag is automatically passed for you by the client when running over a tunnel agent such as <command>ssh</command>. That means there's rarely any need for <emphasis>you</emphasis> to pass this option to <command>svnserve</command>. So if you find yourself typing <literal>svnserve --tunnel</literal> on the command line, and wondering what to do next, see <xref linkend=\"svn.serverconfig.svnserve.sshauth\"/>."
16858 #: ../source/book.xml:23076
16859 msgid "--tunnel-user NAME"
16863 #: ../source/book.xml:23079
16864 msgid "Used in conjunction with the <option>--tunnel</option> option; tells svnserve to assume that <replaceable>NAME</replaceable> is the authenticated user, rather than the UID of the svnserve process. Useful for users wishing to share a single system account over SSH, but maintaining separate commit identities."
16868 #: ../source/book.xml:23089
16869 msgid "<option>--threads</option> (<option>-T</option>)"
16873 #: ../source/book.xml:23091
16874 msgid "When running in daemon mode, causes <command>svnserve</command> to spawn a thread instead of a process for each connection (e.g. for when running on Windows). The <command>svnserve</command> process still backgrounds itself at startup time."
16878 #: ../source/book.xml:23099
16879 msgid "<option>--listen-once</option> (<option>-X</option>)"
16883 #: ../source/book.xml:23101
16884 msgid "Causes <command>svnserve</command> to accept one connection on the svn port, serve it, and exit. This option is mainly useful for debugging."
16888 #: ../source/book.xml:23124
16889 msgid "Summarize the local revision(s) of a working copy."
16893 #: ../source/book.xml:23131
16895 msgid "svnversion [OPTIONS] [WC_PATH [TRAIL_URL]]"
16899 #: ../source/book.xml:23137
16900 msgid "<command>svnversion</command> is a program for summarizing the revision mixture of a working copy. The resultant revision number, or revision range, is written to standard output."
16904 #: ../source/book.xml:23141
16905 msgid "It's common to use this output in your build process when defining the version number of your program."
16909 #: ../source/book.xml:23143
16910 msgid "<replaceable>TRAIL_URL</replaceable>, if present, is the trailing portion of the URL used to determine if <replaceable>WC_PATH</replaceable> itself is switched (detection of switches within <replaceable>WC_PATH</replaceable> does not rely on <replaceable>TRAIL_URL</replaceable>)."
16914 #: ../source/book.xml:23149
16915 msgid "When <replaceable>WC_PATH</replaceable> is not defined, the current directory will be used as the working copy path. <replaceable>TRAIL_URL</replaceable> cannot be defined if <replaceable>WC_PATH</replaceable> is not explicitly given."
16919 #: ../source/book.xml:23159
16920 msgid "Like <command>svnserve</command>, <command>svnversion</command> has no subcommands, it only has options."
16924 #: ../source/book.xml:23164
16925 msgid "<option>--no-newline</option> (<option>-n</option>)"
16929 #: ../source/book.xml:23166
16930 msgid "Omit the usual trailing newline from the output."
16934 #: ../source/book.xml:23170
16935 msgid "<option>--committed</option> (<option>-c</option>)"
16939 #: ../source/book.xml:23172
16940 msgid "Use the last-changed revisions rather than the current (i.e., highest locally available) revisions."
16944 #: ../source/book.xml:23179
16945 msgid "Print a help summary."
16949 #: ../source/book.xml:23187
16950 msgid "Print the version of <command>svnversion</command> and exit with no error."
16954 #: ../source/book.xml:23197
16955 msgid "If the working copy is all at the same revision (for example, immediately after an update), then that revision is printed out:"
16959 #: ../source/book.xml:23200
16961 msgid "\n$ svnversion\n4168\n"
16965 #: ../source/book.xml:23204
16966 msgid "You can add <replaceable>TRAIL_URL</replaceable> to make sure that the working copy is not switched from what you expect. Note that the <replaceable>WC_PATH</replaceable> is required in this command:"
16970 #: ../source/book.xml:23208
16972 msgid "\n$ svnversion . /repos/svn/trunk\n4168\n"
16976 #: ../source/book.xml:23212
16977 msgid "For a mixed-revision working copy, the range of revisions present is printed:"
16981 #: ../source/book.xml:23214
16983 msgid "\n$ svnversion\n4123:4168\n"
16987 #: ../source/book.xml:23218
16988 msgid "If the working copy contains modifications, a trailing \"M\" is added:"
16992 #: ../source/book.xml:23220
16994 msgid "\n$ svnversion\n4168M\n"
16998 #: ../source/book.xml:23224
16999 msgid "If the working copy is switched, a trailing \"S\" is added:"
17003 #: ../source/book.xml:23226
17005 msgid "\n$ svnversion\n4168S\n"
17009 #: ../source/book.xml:23230
17010 msgid "Thus, here is a mixed-revision, switched working copy containing some local modifications:"
17014 #: ../source/book.xml:23232
17016 msgid "\n$ svnversion\n4212:4168MS\n"
17020 #: ../source/book.xml:23236
17021 msgid "If invoked on a directory that is not a working copy, <command>svnversion</command> assumes it is an exported working copy and prints \"exported\":"
17025 #: ../source/book.xml:23239
17027 msgid "\n$ svnversion\nexported\n"
17031 #: ../source/book.xml:23257
17032 msgid "<placeholder-1/> Configuration Directives"
17036 #: ../source/book.xml:23259
17037 msgid "Apache configuration directives for serving Subversion repositories through Apache HTTP Server."
17041 #: ../source/book.xml:23267
17042 msgid "This section briefly describes each of the Subversion Apache configuration directives. For an in-depth description of configuring Apache with Subversion, see <xref linkend=\"svn.serverconfig.httpd\"/>.)"
17046 #: ../source/book.xml:23273
17051 #: ../source/book.xml:23278
17056 #: ../source/book.xml:23281
17057 msgid "This directive must be included in any <literal>Directory</literal> or <literal>Location</literal> block for a Subversion repository. It tells httpd to use the Subversion backend for mod_dav to handle all requests."
17061 #: ../source/book.xml:23290
17062 msgid "SVNAutoversioning On"
17066 #: ../source/book.xml:23293
17067 msgid "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 <literal>ModMimeUsePathInfo On</literal> so that <literal>mod_mime</literal> can set <literal>svn:mime-type</literal> to the correct mime-type automatically (as best as <literal>mod_mime</literal> is able to, of course). For more information, see <xref linkend=\"svn.webdav\"/>"
17071 #: ../source/book.xml:23307
17076 #: ../source/book.xml:23310
17077 msgid "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 <literal>SVNParentPath</literal> must be present, but not both."
17081 #: ../source/book.xml:23320
17082 msgid "SVNSpecialURI"
17086 #: ../source/book.xml:23323
17087 msgid "Specifies the URI component (namespace) for special Subversion resources. The default is <quote><literal>!svn</literal></quote>, and most administrators will never use this directive. Only set this if there is a pressing need to have a file named <filename>!svn</filename> 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."
17091 #: ../source/book.xml:23337
17092 msgid "SVNReposName"
17096 #: ../source/book.xml:23340
17097 msgid "Specifies the name of a Subversion repository for use in <literal>HTTP GET</literal> responses. 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."
17101 #: ../source/book.xml:23350
17102 msgid "SVNIndexXSLT"
17106 #: ../source/book.xml:23353
17107 msgid "Specifies the URI of an XSL transformation for directory indexes. This directive is optional."
17111 #: ../source/book.xml:23359
17112 msgid "SVNParentPath"
17116 #: ../source/book.xml:23362
17117 msgid "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 <literal>SVNPath</literal> must be present, but not both."
17121 #: ../source/book.xml:23372
17122 msgid "SVNPathAuthz"
17126 #: ../source/book.xml:23375
17127 msgid "Control path-based authorization by enabling or disabling subrequests. See <xref linkend=\"svn.serverconfig.httpd.authz.pathauthzoff\"/> for details."
17131 #: ../source/book.xml:23388
17132 msgid "Subversion properties"
17136 #: ../source/book.xml:23390
17137 msgid "Subversion allows users to invent arbitrarily-named versioned properties on files and directories, as well as unversioned properties on revisions. The only restriction is on properties whose names begin with <literal>svn:</literal> (those are reserved for Subversion's own use). While these properties may be set by users to control Subversion's behavior, users may not invent new <literal>svn:</literal> properties."
17141 #: ../source/book.xml:23399
17142 msgid "Versioned Properties"
17146 #: ../source/book.xml:23404
17147 msgid "svn:executable"
17151 #: ../source/book.xml:23407
17152 msgid "If present on a file, the client will make the file executable in Unix-hosted working copies. See <xref linkend=\"svn.advanced.props.special.executable\"/>."
17156 #: ../source/book.xml:23414
17157 msgid "svn:mime-type"
17161 #: ../source/book.xml:23417
17162 msgid "If present on a file, the value indicates the file's mime-type. This allows the client to decide whether line-based contextual merging is safe to perform during updates, and can also affect how the file behaves when fetched via web browser. See <xref linkend=\"svn.advanced.props.special.mime-type\"/>."
17166 #: ../source/book.xml:23427
17171 #: ../source/book.xml:23430
17172 msgid "If present on a directory, the value is a list of <emphasis>unversioned</emphasis> file patterns to be ignored by <command>svn status</command> and other subcommands. See <xref linkend=\"svn.advanced.props.special.ignore\"/>"
17176 #: ../source/book.xml:23439
17177 msgid "svn:keywords"
17181 #: ../source/book.xml:23442
17182 msgid "If present on a file, the value tells the client how to expand particular keywords within the file. See <xref linkend=\"svn.advanced.props.special.keywords\"/>."
17186 #: ../source/book.xml:23450
17187 msgid "svn:eol-style"
17191 #: ../source/book.xml:23453
17192 msgid "If present on a file, the value tells the client how to manipulate the file's line-endings in the working copy, and in exported trees. See <xref linkend=\"svn.advanced.props.special.eol-style\"/> and <xref linkend=\"svn.ref.svn.c.export\"/>."
17196 #: ../source/book.xml:23461
17197 msgid "svn:externals"
17201 #: ../source/book.xml:23464
17202 msgid "If present on a directory, the value is a multi-line list of other paths and URLs the client should check out. See <xref linkend=\"svn.advanced.externals\"/>."
17206 #: ../source/book.xml:23472
17207 msgid "svn:special"
17211 #: ../source/book.xml:23477
17212 msgid "As of this writing, symbolic links are indeed the only <quote>special</quote> objects. But there might be more in future releases of Subversion."
17216 #: ../source/book.xml:23475
17217 msgid "If present on a file, indicates that the file is not an ordinary file, but a symbolic link or other special object<placeholder-1/>."
17221 #: ../source/book.xml:23485
17222 msgid "svn:needs-lock"
17226 #: ../source/book.xml:23488
17227 msgid "If present on a file, tells the client to make the file read-only in the working copy, as a reminder that the file should be locked before editing begins. See <xref linkend=\"svn.advanced.locking.lock-communication\"/>."
17231 #: ../source/book.xml:23498
17232 msgid "Unversioned Properties"
17236 #: ../source/book.xml:23503
17241 #: ../source/book.xml:23506
17242 msgid "If present, contains the authenticated username of the person who created the revision. (If not present, then the revision was committed anonymously.)"
17246 #: ../source/book.xml:23513
17251 #: ../source/book.xml:23516
17252 msgid "Contains the UTC time the revision was created, in ISO 8601 format. The value comes from the <emphasis>server</emphasis> machine's clock, not the client's."
17256 #: ../source/book.xml:23524
17261 #: ../source/book.xml:23527
17262 msgid "Contains the log message describing the revision."
17266 #: ../source/book.xml:23533
17267 msgid "svn:autoversioned"
17271 #: ../source/book.xml:23536
17272 msgid "If present, the revision was created via the autoversioning feature. See <xref linkend=\"svn.webdav.autoversioning\"/>."
17276 #: ../source/book.xml:23549
17277 msgid "Repository Hooks"
17281 #: ../source/book.xml:23554 ../source/book.xml:23601 ../source/book.xml:23650 ../source/book.xml:23696 ../source/book.xml:23759 ../source/book.xml:23821 ../source/book.xml:23872 ../source/book.xml:23918 ../source/book.xml:23971
17285 #.(tertiary), (refname)
17286 #: ../source/book.xml:23556 ../source/book.xml:23559
17287 msgid "start-commit"
17291 #: ../source/book.xml:23560
17292 msgid "Notification of the beginning of a commit."
17296 #: ../source/book.xml:23566
17297 msgid "The start-commit hook is run before the commit transaction is even created. It is typically used to decide if the user has commit privileges at all."
17301 #: ../source/book.xml:23569
17302 msgid "If the start-commit hook program returns a non-zero exit value, the commit is stopped before the commit transaction is even created, and anything printed to stderr is marshalled back to the client."
17306 #: ../source/book.xml:23576 ../source/book.xml:23627 ../source/book.xml:23673 ../source/book.xml:23723 ../source/book.xml:23785 ../source/book.xml:23845 ../source/book.xml:23892 ../source/book.xml:23944 ../source/book.xml:23991
17307 msgid "Input Parameter(s)"
17311 #: ../source/book.xml:23578 ../source/book.xml:23629 ../source/book.xml:23675 ../source/book.xml:23725 ../source/book.xml:23787 ../source/book.xml:23847 ../source/book.xml:23894 ../source/book.xml:23946 ../source/book.xml:23993
17312 msgid "The command-line arguments passed to the hook program, in order, are:"
17316 #: ../source/book.xml:23582 ../source/book.xml:23633 ../source/book.xml:23679 ../source/book.xml:23729 ../source/book.xml:23791 ../source/book.xml:23851 ../source/book.xml:23898 ../source/book.xml:23950 ../source/book.xml:23997
17317 msgid "repository path"
17321 #: ../source/book.xml:23585
17322 msgid "authenticated username attempting the commit"
17326 #: ../source/book.xml:23591 ../source/book.xml:23642 ../source/book.xml:23688 ../source/book.xml:23751 ../source/book.xml:23813 ../source/book.xml:23864 ../source/book.xml:23910 ../source/book.xml:23963 ../source/book.xml:24009
17327 msgid "Common Uses"
17331 #: ../source/book.xml:23593 ../source/book.xml:23866 ../source/book.xml:23965
17332 msgid "access control"
17335 #.(tertiary), (refname)
17336 #: ../source/book.xml:23603 ../source/book.xml:23606
17341 #: ../source/book.xml:23607
17342 msgid "Notification just prior to commit completion."
17346 #: ../source/book.xml:23613
17347 msgid "The pre-commit hook is run just before a commit transaction is promoted to a new revision. Typically, this hook is used to protect against commits that are disallowed due to content or location (for example, your site might require that all commits to a certain branch include a ticket number from the bug tracker, or that the incoming log message is non-empty)."
17351 #: ../source/book.xml:23620
17352 msgid "If the pre-commit hook program returns a non-zero exit value, the commit is aborted, the commit transaction is removed, and anything printed to stderr is marshalled back to the client."
17356 #: ../source/book.xml:23636
17357 msgid "commit transaction name"
17361 #: ../source/book.xml:23644
17362 msgid "change validation and control"
17365 #.(tertiary), (refname)
17366 #: ../source/book.xml:23652 ../source/book.xml:23655
17367 msgid "post-commit"
17371 #: ../source/book.xml:23656
17372 msgid "Notification of a successful commit."
17376 #: ../source/book.xml:23662
17377 msgid "The post-commit hook is run after the transaction is committed, and a new revision created. Most people use this hook to send out descriptive emails about the commit or to notify some other tool (such as an issue tracker) that a commit has happened. Some configurations also use this hook to trigger backup processes."
17381 #: ../source/book.xml:23668
17382 msgid "The output from, and exit value returned by the post-commit hook program are ignored."
17386 #: ../source/book.xml:23682
17387 msgid "revision number created by the commit"
17391 #: ../source/book.xml:23690
17392 msgid "commit notification, tool integration"
17395 #.(tertiary), (refname)
17396 #: ../source/book.xml:23698 ../source/book.xml:23701
17397 msgid "pre-revprop-change"
17401 #: ../source/book.xml:23702
17402 msgid "Notification of a revision property change attempt."
17406 #: ../source/book.xml:23709
17407 msgid "The pre-revprop-change hook is run immediately prior to the modification of a revision property when performed outside the scope of a normal commit. Unlike the other hooks, the default state of this one is to deny the proposed action. The hook must actually exist and return a zero exit value before a revision property modification can happen."
17411 #: ../source/book.xml:23716
17412 msgid "If the pre-revprop-change hook doesn't exist, isn't executable, or returns a non-zero exit value, no change to the property will be made, and anything printed to stderr is marshalled back to the client."
17416 #: ../source/book.xml:23732
17417 msgid "revision whose property is about to be modified"
17421 #: ../source/book.xml:23735
17422 msgid "authenticated username attempting the propchange"
17426 #: ../source/book.xml:23738 ../source/book.xml:23800
17427 msgid "name of the property changed"
17431 #: ../source/book.xml:23741 ../source/book.xml:23803
17432 msgid "change description: <literal>A</literal> (added), <literal>D</literal> (deleted), or <literal>M</literal> (modified)"
17436 #: ../source/book.xml:23746
17437 msgid "Additionally, Subversion passes to the hook program via standard input the proposed value of the property."
17441 #: ../source/book.xml:23753
17442 msgid "access control, change validation and control"
17445 #.(tertiary), (refname)
17446 #: ../source/book.xml:23761 ../source/book.xml:23764
17447 msgid "post-revprop-change"
17451 #: ../source/book.xml:23765
17452 msgid "Notification of a successful revision property change."
17456 #: ../source/book.xml:23772
17457 msgid "The post-revprop-change hook is run immediately after to the modification of a revision property when performed outside the scope of a normal commit. As can be derived from the description of its counterpart, the pre-revprop-change hook, this hook will not run at all unless the pre-revprop-change hook is implemented. It is typically used to send email notification of the property change."
17461 #: ../source/book.xml:23780
17462 msgid "The output from, and exit value returned by, the post-revprop-change hook program are ignored."
17466 #: ../source/book.xml:23794
17467 msgid "revision whose property was modified"
17471 #: ../source/book.xml:23797
17472 msgid "authenticated username of the person making the change"
17476 #: ../source/book.xml:23808
17477 msgid "Additionally, Subversion passes to the hook program, via standard input, the previous value of the property."
17481 #: ../source/book.xml:23815
17482 msgid "propchange notification"
17485 #.(tertiary), (refname)
17486 #: ../source/book.xml:23823 ../source/book.xml:23826
17491 #: ../source/book.xml:23827
17492 msgid "Notification of a path lock attempt."
17496 #: ../source/book.xml:23833
17497 msgid "The pre-lock hook runs whenever someone attempts to lock a path. It can be used to prevent locks altogether, or to create a more complex policy specifying exactly which users are allowed to lock particular paths. If the hook notices a pre-existing lock, then it can also decide whether a user is allowed to <quote>steal</quote> the existing lock."
17501 #: ../source/book.xml:23839
17502 msgid "If the pre-lock hook program returns a non-zero exit value, the lock action is aborted and anything printed to stderr is marshalled back to the client."
17506 #: ../source/book.xml:23854 ../source/book.xml:23953
17507 msgid "versioned path which is to be locked"
17511 #: ../source/book.xml:23857 ../source/book.xml:23956
17512 msgid "authenticated username of the person attempting the lock"
17515 #.(tertiary), (refname)
17516 #: ../source/book.xml:23874 ../source/book.xml:23877
17521 #: ../source/book.xml:23878
17522 msgid "Notification of a successful path lock."
17526 #: ../source/book.xml:23884
17527 msgid "The post-lock hook runs after one or more paths has been locked. It is typically used to send email notification of the lock event."
17531 #: ../source/book.xml:23887
17532 msgid "The output from and exit value returned by the post-lock hook program are ignored."
17536 #: ../source/book.xml:23901
17537 msgid "authenticated username of the person who locked the paths"
17541 #: ../source/book.xml:23905
17542 msgid "Additionally, the list of paths locked is passed to the hook program via standard input, one path per line."
17546 #: ../source/book.xml:23912
17547 msgid "lock notification"
17550 #.(tertiary), (refname)
17551 #: ../source/book.xml:23920 ../source/book.xml:23923
17556 #: ../source/book.xml:23924
17557 msgid "Notification of a path unlock attempt."
17561 #: ../source/book.xml:23930
17562 msgid "The pre-unlock hook runs whenever someone attempts to remove a lock on a file. It can be used to create policies that specify which users are allowed to unlock particular paths. It's particularly important for determining policies about lock breakage. If user A locks a file, is user B allowed to break the lock? What if the lock is more than a week old? These sorts of things can be decided and enforced by the hook."
17566 #: ../source/book.xml:23938
17567 msgid "If the pre-unlock hook program returns a non-zero exit value, the unlock action is aborted and anything printed to stderr is marshalled back to the client."
17570 #.(tertiary), (refname)
17571 #: ../source/book.xml:23973 ../source/book.xml:23976
17572 msgid "post-unlock"
17576 #: ../source/book.xml:23977
17577 msgid "Notification of a successful path unlock."
17581 #: ../source/book.xml:23983
17582 msgid "The post-unlock hook runs after one or more paths has been unlocked. It is typically used to send email notification of the unlock event."
17586 #: ../source/book.xml:23986
17587 msgid "The output from and exit value returned by, the post-unlock hook program are ignored."
17591 #: ../source/book.xml:24000
17592 msgid "authenticated username of the person who unlocked the paths"
17596 #: ../source/book.xml:24004
17597 msgid "Additionally, the list of paths unlocked is passed to the hook program via standard input, one path per line."
17601 #: ../source/book.xml:24011
17602 msgid "unlock notification"
17606 #: ../source/book.xml:24023
17607 msgid "Subversion Quick-Start Guide"
17611 #: ../source/book.xml:24025
17612 msgid "If you're eager to get Subversion up and running (and you enjoy learning by experimentation), this chapter will show you how to create a repository, import code, and then check it back out again as a working copy. Along the way, we give links to the relevant chapters of this book."
17616 #: ../source/book.xml:24031
17617 msgid "If you're new to the entire concept of version control or to the <quote>copy-modify-merge</quote> model used by both CVS and Subversion, then you should read <xref linkend=\"svn.basic\"/> before going any further."
17621 #: ../source/book.xml:24041
17622 msgid "Installing Subversion"
17626 #: ../source/book.xml:24043
17627 msgid "Subversion is built on a portability layer called APR—the Apache Portable Runtime library. The APR library provides all the interfaces that Subversion needs to function on different operating systems: disk access, network access, memory management, and so on. While Subversion is able to use Apache as one of its network server programs, its dependence on APR <emphasis>does not</emphasis> mean that Apache is a required component. APR is a standalone library useable by any application. It does mean, however, that like Apache, Subversion clients and servers run on any operating system that the Apache httpd server runs on: Windows, Linux, all flavors of BSD, Mac OS X, Netware, and others."
17631 #: ../source/book.xml:24055
17632 msgid "The easiest way to get Subversion is to download a binary package built for your operating system. Subversion's website (<uri href=\"http://subversion.tigris.org\">http://subversion.tigris.org</uri>) often has these packages available for download, posted by volunteers. The site usually contains graphical installer packages for users of Microsoft operating systems. If you run a Unix-like operating system, you can use your system's native package distribution system (RPMs, DEBs, the ports tree, etc.) to get Subversion."
17636 #: ../source/book.xml:24064
17637 msgid "Alternately, you can build Subversion directly from source code, though it's not always an easy task. (If you're not experienced at building open source software packages, you're probably better off downloading a binary distribution instead!) From the Subversion website, download the latest source-code release. After unpacking it, follow the instructions in the <filename>INSTALL</filename> file to build it. Note that a released source package may not contain everything you need to build a command-line client capable of talking to a remote repository. Starting with Subversion 1.4 and later, the libraries Subversion depends on (apr, apr-util, and neon) are distributed in a separate source package suffixed with <filename>-deps</filename>. These libraries are now common enough that they may already be installed on your system. If not, you'll need to unpack the dependency package into the same directory where you unpacked the main Subversion source. Regardless, it's possible that you may want to fetch other optional dependencies such as Berkeley DB and possibly Apache httpd. If you want to do a complete build, make sure you have all of the packages documented in the <filename>INSTALL</filename> file."
17641 #: ../source/book.xml:24091
17642 msgid "Note that the URL checked out in the example above ends not with <literal>svn</literal>, but with a subdirectory thereof called <literal>trunk</literal>. See our discussion of Subversion's branching and tagging model for the reasoning behind this."
17646 #: ../source/book.xml:24085
17647 msgid "If you're one of those folks that likes to use bleeding-edge software, you can also get the Subversion source code from the Subversion repository in which it lives. Obviously, you'll need to already have a Subversion client on hand to do this. But once you do, you can check out a working copy of the Subversion source repository from <uri href=\"http://svn.collab.net/repos/svn/trunk/\">http://svn.collab.net/repos/svn/trunk/</uri>: <placeholder-1/>"
17651 #: ../source/book.xml:24096
17653 msgid "\n$ svn checkout http://svn.collab.net/repos/svn/trunk subversion\nA subversion/HACKING\nA subversion/INSTALL\nA subversion/README\nA subversion/autogen.sh\nA subversion/build.conf\n…\n"
17657 #: ../source/book.xml:24105
17658 msgid "The above command will create a working copy of the latest (unreleased) Subversion source code into a subdirectory named <filename>subversion</filename> in your current working directory. 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 <filename>INSTALL</filename> file in the top level of the working copy for details."
17662 #: ../source/book.xml:24121
17663 msgid "High-speed Tutorial"
17667 #: ../source/book.xml:24125
17668 msgid "Please make sure your seat backs are in their full, upright position, and that your tray tables are stored. Flight attendants, prepare for take-off…."
17672 #: ../source/book.xml:24130
17673 msgid "What follows is a quick tutorial that walks you through some basic Subversion configuration and operation. When you finish it, you should have a basic understanding of Subversion's typical usage."
17677 #: ../source/book.xml:24135
17678 msgid "The examples used in this appendix assume that you have <command>svn</command>, the Subversion command-line client, and <command>svnadmin</command>, the administrative tool, ready to go on a Unix-like operating system. (This tutorial also works at the Windows commandline prompt, assuming you make some obvious tweaks.) We also assume you are using Subversion 1.2 or later (run <command>svn --version</command> to check.)"
17682 #: ../source/book.xml:24144
17683 msgid "Subversion stores all versioned data in a central repository. To begin, create a new repository:"
17687 #: ../source/book.xml:24146
17689 msgid "\n$ svnadmin create /path/to/repos\n$ ls /path/to/repos\nconf/ dav/ db/ format hooks/ locks/ README.txt\n"
17693 #: ../source/book.xml:24151
17694 msgid "This command creates a new directory <filename>/path/to/repos</filename> which contains a Subversion repository. This new directory contains (among other things) a collection of database files. You won't see your versioned files if you peek inside. For more information about repository creation and maintenance, see <xref linkend=\"svn.reposadmin\"/>."
17698 #: ../source/book.xml:24158
17699 msgid "Subversion has no concept of a <quote>project</quote>. The repository is just a virtual versioned filesystem, a large tree that can hold anything you wish. Some administrators prefer to store only one project in a repository, and others prefer to store multiple projects in a repository by placing them into separate directories. The merits of each approach are discussed in <xref linkend=\"svn.reposadmin.projects.chooselayout\"/>. Either way, the repository only manages files and directories, so it's up to humans to interpret particular directories as <quote>projects</quote>. So while you might see references to projects throughout this book, keep in mind that we're only ever talking about some directory (or collection of directories) in the repository."
17703 #: ../source/book.xml:24171
17704 msgid "In this example, we assume that you already have some sort of project (a collection of files and directories) that you wish to import into your newly created Subversion repository. Begin by organizing your data into a single directory called <filename>myproject</filename> (or whatever you wish). For reasons that will be clear later (see <xref linkend=\"svn.branchmerge\"/>), your project's tree structure should contain three top-level directories named <filename>branches</filename>, <filename>tags</filename>, and <filename>trunk</filename>. The <filename>trunk</filename> directory should contain all of your data, while <filename>branches</filename> and <filename>tags</filename> directories are empty:"
17708 #: ../source/book.xml:24185
17710 msgid "\n/tmp/myproject/branches/\n/tmp/myproject/tags/\n/tmp/myproject/trunk/\n foo.c\n bar.c\n Makefile\n …\n"
17714 #: ../source/book.xml:24194
17715 msgid "The <filename>branches</filename>, <filename>tags</filename>, and <filename>trunk</filename> subdirectories aren't actually required by Subversion. They're merely a popular convention that you'll most likely want to use later on."
17719 #: ../source/book.xml:24198
17720 msgid "Once you have your tree of data ready to go, import it into the repository with the <command>svn import</command> command (see <xref linkend=\"svn.tour.importing\"/>):"
17724 #: ../source/book.xml:24201
17726 msgid "\n$ svn import /tmp/myproject file:///path/to/repos/myproject -m \"initial import\"\nAdding /tmp/myproject/branches\nAdding /tmp/myproject/tags\nAdding /tmp/myproject/trunk\nAdding /tmp/myproject/trunk/foo.c\nAdding /tmp/myproject/trunk/bar.c\nAdding /tmp/myproject/trunk/Makefile\n…\nCommitted revision 1.\n$ \n"
17730 #: ../source/book.xml:24213
17731 msgid "Now the repository contains this tree of data. As mentioned earlier, you won't see your files by directly peeking into the repository; they're all stored within a database. But the repository's imaginary filesystem now contains a top-level directory named <filename>myproject</filename>, which in turn contains your data."
17735 #: ../source/book.xml:24219
17736 msgid "Note that the original <filename>/tmp/myproject</filename> directory is unchanged; Subversion is unaware of it. (In fact, you can even delete that directory if you wish.) In order to start manipulating repository data, you need to create a new <quote>working copy</quote> of the data, a sort of private workspace. Ask Subversion to <quote>check out</quote> a working copy of the <filename>myproject/trunk</filename> directory in the repository:"
17740 #: ../source/book.xml:24227
17742 msgid "\n$ svn checkout file:///path/to/repos/myproject/trunk myproject\nA myproject/foo.c\nA myproject/bar.c\nA myproject/Makefile\n…\nChecked out revision 1.\n"
17746 #: ../source/book.xml:24235
17747 msgid "Now you have a personal copy of part of the repository in a new directory named <filename>myproject</filename>. You can edit the files in your working copy and then commit those changes back into the repository."
17751 #: ../source/book.xml:24241
17752 msgid "Enter your working copy and edit a file's contents."
17756 #: ../source/book.xml:24245
17757 msgid "Run <command>svn diff</command> to see unified diff output of your changes."
17761 #: ../source/book.xml:24249
17762 msgid "Run <command>svn commit</command> to commit the new version of your file to the repository."
17766 #: ../source/book.xml:24253
17767 msgid "Run <command>svn update</command> to bring your working copy <quote>up-to-date</quote> with the repository."
17771 #: ../source/book.xml:24257
17772 msgid "For a full tour of all the things you can do with your working copy, read <xref linkend=\"svn.tour\"/>."
17776 #: ../source/book.xml:24259
17777 msgid "At this point, you have the option of making your repository available to others over a network. See <xref linkend=\"svn.serverconfig\"/> to learn about the different sorts of server processes available and how to configure them."
17781 #: ../source/book.xml:24273
17782 msgid "Subversion for CVS Users"
17786 #: ../source/book.xml:24275
17787 msgid "This appendix is a guide for CVS users new to Subversion. It's essentially a list of differences between the two systems as <quote>viewed from 10,000 feet</quote>. For each section, we provide backreferences to relevant chapters when possible."
17791 #: ../source/book.xml:24280
17792 msgid "Although the goal of Subversion is to take over the current and future CVS user base, some new features and design changes were required to fix certain <quote>broken</quote> behaviors that CVS had. This means that, as a CVS user, you may need to break habits—ones that you forgot were odd to begin with."
17796 #: ../source/book.xml:24291
17797 msgid "Revision Numbers Are Different Now"
17801 #: ../source/book.xml:24293
17802 msgid "In CVS, revision numbers are per-file. This is because CVS stores its data in RCS files; each file has a corresponding RCS file in the repository, and the repository is roughly laid out according to the structure of your project tree."
17806 #: ../source/book.xml:24297
17807 msgid "In Subversion, the repository looks like a single filesystem. Each commit results in an entirely new filesystem tree; in essence, the repository is an array of trees. Each of these trees is labeled with a single revision number. When someone talks about <quote>revision 54</quote>, they're talking about a particular tree (and indirectly, the way the filesystem looked after the 54th commit)."
17811 #: ../source/book.xml:24304
17812 msgid "Technically, it's not valid to talk about <quote>revision 5 of <filename>foo.c</filename></quote>. Instead, one would say <quote><filename>foo.c</filename> as it appears in revision 5</quote>. Also, be careful when making assumptions about the evolution of a file. In CVS, revisions 5 and 6 of <filename>foo.c</filename> are always different. In Subversion, it's most likely that <filename>foo.c</filename> did <emphasis>not</emphasis> change between revisions 5 and 6."
17816 #: ../source/book.xml:24313
17817 msgid "Similarly, in CVS a tag or branch is an annotation on the file, or on the version information for that individual file, whereas in Subversion a tag or branch is a copy of an entire tree (by convention, into the <filename>/branches</filename> or <filename>/tags</filename> directories that appear at the top level of the repository, beside <filename>/trunk</filename>). In the repository as a whole, many versions of each file may be visible: the latest version on each branch, every tagged version, and of course the latest version on the trunk itself. So, to refine the terms even further, one would often say <quote><filename>foo.c</filename> as it appears in <filename>/branches/REL1</filename> in revision 5.</quote>"
17821 #: ../source/book.xml:24326
17822 msgid "For more details on this topic, see <xref linkend=\"svn.basic.in-action.revs\"/>."
17826 #: ../source/book.xml:24333
17827 msgid "Directory Versions"
17831 #: ../source/book.xml:24335
17832 msgid "Subversion tracks tree structures, not just file contents. It's one of the biggest reasons Subversion was written to replace CVS."
17836 #: ../source/book.xml:24338
17837 msgid "Here's what this means to you, as a former CVS user:"
17841 #: ../source/book.xml:24341
17842 msgid "The <command>svn add</command> and <command>svn delete</command> commands work on directories now, just as they work on files. So do <command>svn copy</command> and <command>svn move</command>. However, these commands do <emphasis>not</emphasis> cause any kind of immediate change in the repository. Instead, the working items are simply <quote>scheduled</quote> for addition or deletion. No repository changes happen until you run <command>svn commit</command>."
17846 #: ../source/book.xml:24352
17847 msgid "Directories aren't dumb containers anymore; they have revision numbers like files. (Or more properly, it's correct to talk about <quote>directory <filename>foo/</filename> in revision 5</quote>.)"
17851 #: ../source/book.xml:24358
17852 msgid "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."
17856 #: ../source/book.xml:24362
17857 msgid "From a theoretical point of view, we define <quote>revision 5 of directory <filename>foo</filename></quote> to mean a specific collection of directory-entries and properties. Now suppose we start adding and removing files from <filename>foo</filename>, and then commit. It would be a lie to say that we still have revision 5 of <filename>foo</filename>. However, if we bumped <filename>foo</filename>'s revision number after the commit, that would be a lie too; there may be other changes to <filename>foo</filename> we haven't yet received, because we haven't updated yet."
17861 #: ../source/book.xml:24373
17862 msgid "Subversion deals with this problem by quietly tracking committed adds and deletes in the <filename>.svn</filename> area. When you eventually run <command>svn update</command>, all accounts are settled with the repository, and the directory's new revision number is set correctly. <emphasis>Therefore, only after an update is it truly safe to say that you have a <quote>perfect</quote> revision of a directory.</emphasis> Most of the time, your working copy will contain <quote>imperfect</quote> directory revisions."
17866 #: ../source/book.xml:24382
17867 msgid "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. <emphasis>Therefore, you are not allowed to commit property-changes on a directory unless the directory is up-to-date.</emphasis>"
17871 #: ../source/book.xml:24390
17872 msgid "For more discussion about the limitations of directory versioning, see <xref linkend=\"svn.basic.in-action.mixedrevs\"/>."
17876 #: ../source/book.xml:24398
17877 msgid "More Disconnected Operations"
17881 #: ../source/book.xml:24400
17882 msgid "In recent years, disk space has become outrageously cheap and abundant, but network bandwidth has not. Therefore, the Subversion working copy has been optimized around the scarcer resource."
17886 #: ../source/book.xml:24404
17887 msgid "The <filename>.svn</filename> administrative directory serves the same purpose as the <filename>CVS</filename> directory, except that it also stores read-only, <quote>pristine</quote> copies of your files. This allows you to do many things off-line:"
17891 #: ../source/book.xml:24415
17892 msgid "Shows you any local changes you've made (see <xref linkend=\"svn.tour.cycle.examine.status\"/>)"
17896 #: ../source/book.xml:24423
17897 msgid "Shows you the details of your changes (see <xref linkend=\"svn.tour.cycle.examine.diff\"/>)"
17901 #: ../source/book.xml:24431
17902 msgid "Removes your local changes (see <xref linkend=\"svn.tour.cycle.revert\"/>)"
17906 #: ../source/book.xml:24435
17907 msgid "Also, the cached pristine files allow the Subversion client to send differences when committing, which CVS cannot do."
17911 #: ../source/book.xml:24437
17912 msgid "The last subcommand in the list is new; it will not only remove local changes, but it will un-schedule operations such as adds and deletes. It's the preferred way to revert a file; running <command>rm file; svn update</command> will still work, but it blurs the purpose of updating. And, while we're on this subject…"
17916 #: ../source/book.xml:24451
17917 msgid "Distinction Between Status and Update"
17921 #: ../source/book.xml:24453
17922 msgid "In Subversion, we've tried to erase a lot of the confusion between the <command>cvs status</command> and <command>cvs update</command> commands."
17926 #: ../source/book.xml:24456
17927 msgid "The <command>cvs status</command> 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 <command>cvs update</command> or <command>cvs -n update</command> to quickly see their changes. If users forget to use the <option>-n</option> option, this has the side effect of merging repository changes they may not be ready to deal with."
17931 #: ../source/book.xml:24467
17932 msgid "With Subversion, we've tried to remove this muddle by making the output of <command>svn status</command> easy to read for both humans and parsers. Also, <command>svn update</command> only prints information about files that are updated, <emphasis>not</emphasis> local modifications."
17936 #: ../source/book.xml:24474
17941 #: ../source/book.xml:24476
17942 msgid "<command>svn status</command> prints all files that have local modifications. By default, the repository is not contacted. While this subcommand accepts a fair number of options, the following are the most commonly used ones:"
17946 #: ../source/book.xml:24483
17951 #: ../source/book.xml:24486
17952 msgid "Contact the repository to determine, and then display, out-of-dateness information."
17956 #: ../source/book.xml:24492
17961 #: ../source/book.xml:24495
17962 msgid "Show <emphasis>all</emphasis> entries under version control."
17966 #: ../source/book.xml:24501
17971 #: ../source/book.xml:24504
17972 msgid "Run non-recursively (do not descend into subdirectories)."
17976 #: ../source/book.xml:24509
17977 msgid "The <command>status</command> command has two output formats. In the default <quote>short</quote> format, local modifications look like this:"
17981 #: ../source/book.xml:24512
17983 msgid "\n$ svn status\nM foo.c\nM bar/baz.c\n"
17987 #: ../source/book.xml:24517
17988 msgid "If you specify the <option>--show-updates</option> (<option>-u</option>) option, a longer output format is used:"
17992 #: ../source/book.xml:24520
17994 msgid "\n$ svn status -u\nM 1047 foo.c\n * 1045 faces.html\n * bloo.png\nM 1050 bar/baz.c\nStatus against revision: 1066\n"
17998 #: ../source/book.xml:24528
17999 msgid "In this case, two new columns appear. The second column contains an asterisk if the file or directory is out-of-date. The third column shows the working-copy's revision number of the item. In the example above, the asterisk indicates that <filename>faces.html</filename> would be patched if we updated, and that <filename>bloo.png</filename> is a newly added file in the repository. (The absence of any revision number next to <filename>bloo.png</filename> means that it doesn't yet exist in the working copy.)"
18002 #. ###TODO describe -v here as well as -uv. -u and -v use
18003 #. different <quote>long</quote> formats and need to be
18004 #. documented separately. Moreover, as you can combine -u and
18005 #. -v, it needs to be explained what each of them does. As -u is
18006 #. much more important than -v, and the example following that
18007 #. paragraph *is* about -u, not -v, my patch concentrated on
18010 #: ../source/book.xml:24544
18011 msgid "At this point, you should take a quick look at the list of all possible status codes in <xref linkend=\"svn.ref.svn.c.status\"/>. Here are a few of the more common status codes you'll see:"
18015 #: ../source/book.xml:24548
18017 msgid "\nA Resource is scheduled for Addition\nD Resource is scheduled for Deletion\nM Resource has local Modifications\nC Resource has Conflicts (changes have not been completely merged\n between the repository and working copy version)\nX Resource is eXternal to this working copy (may come from another\n repository). See <xref linkend=\"svn.advanced.externals\"></xref>\n? Resource is not under version control\n! Resource is missing or incomplete (removed by another tool than\n Subversion)\n"
18021 #: ../source/book.xml:24560
18022 msgid "For a more detailed discussion of <command>svn status</command>, see <xref linkend=\"svn.tour.cycle.examine.status\"/>."
18026 #: ../source/book.xml:24565
18031 #: ../source/book.xml:24567
18032 msgid "<command>svn update</command> updates your working copy, and only prints information about files that it updates."
18036 #: ../source/book.xml:24569
18037 msgid "Subversion has combined the CVS <literal>P</literal> and <literal>U</literal> codes into just <literal>U</literal>. When a merge or conflict occurs, Subversion simply prints <literal>G</literal> or <literal>C</literal>, rather than a whole sentence about it."
18041 #: ../source/book.xml:24574
18042 msgid "For a more detailed discussion of <command>svn update</command>, see <xref linkend=\"svn.tour.cycle.update\"/>."
18046 #: ../source/book.xml:24583
18047 msgid "Branches and Tags"
18051 #: ../source/book.xml:24585
18052 msgid "Subversion doesn't distinguish between filesystem space and <quote>branch</quote> 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 <xref linkend=\"svn.branchmerge\"/>."
18056 #: ../source/book.xml:24600
18057 msgid "That is, providing you don't run out of disk space before your checkout finishes."
18061 #: ../source/book.xml:24591
18062 msgid "Since Subversion treats branches and tags as ordinary directories, always remember to check out the <literal>trunk</literal> (<literal>http://svn.example.com/repos/calc/trunk/</literal>) of your project, and not the project itself (<literal>http://svn.example.com/repos/calc/</literal>). If you make the mistake of checking out the project itself, you'll wind up with a working copy that contains a copy of your project for every branch and tag you have.<placeholder-1/>"
18066 #: ../source/book.xml:24610
18067 msgid "Metadata Properties"
18071 #: ../source/book.xml:24612
18072 msgid "A new feature of Subversion is that you can attach arbitrary metadata (or <quote>properties</quote>) to files and directories. Properties are arbitrary name/value pairs associated with files and directories in your working copy."
18076 #: ../source/book.xml:24617
18077 msgid "To set or get a property name, use the <command>svn propset</command> and <command>svn propget</command> subcommands. To list all properties on an object, use <command>svn proplist</command>."
18081 #: ../source/book.xml:24621
18082 msgid "For more information, see <xref linkend=\"svn.advanced.props\"/>."
18086 #: ../source/book.xml:24628
18087 msgid "Conflict Resolution"
18091 #: ../source/book.xml:24630
18092 msgid "CVS marks conflicts with in-line <quote>conflict markers</quote>, and prints a <literal>C</literal> during an update. Historically, this has caused problems, because CVS isn't doing enough. Many users forget about (or don't see) the <literal>C</literal> 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."
18096 #: ../source/book.xml:24638
18097 msgid "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 <command>svn resolved</command>. See <xref linkend=\"svn.tour.cycle.resolve\"/> for more details."
18101 #: ../source/book.xml:24648
18102 msgid "Binary Files and Translation"
18106 #: ../source/book.xml:24650
18107 msgid "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."
18111 #: ../source/book.xml:24657
18112 msgid "CVS users have to mark binary files with <option>-kb</option> flags, to prevent data from being garbled (due to keyword expansion and line-ending translations). They sometimes forget to do this."
18116 #: ../source/book.xml:24661
18117 msgid "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 <xref linkend=\"svn.advanced.props.special.keywords\"/> and <xref linkend=\"svn.advanced.props.special.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."
18121 #: ../source/book.xml:24667
18122 msgid "Second, Subversion maintains an internal notion of whether a file is <quote>text</quote> or <quote>binary</quote> data, but this notion is <emphasis>only</emphasis> extant in the working copy. During an <command>svn update</command>, Subversion will perform contextual merges on locally modified text files, but will not attempt to do so for binary files."
18126 #: ../source/book.xml:24673
18127 msgid "To determine whether a contextual merge is possible, Subversion examines the <literal>svn:mime-type</literal> property. If the file has no <literal>svn:mime-type</literal> property, or has a mime-type that is textual (e.g. <literal>text/*</literal>), Subversion assumes it is text. Otherwise, Subversion assumes the file is binary. Subversion also helps users by running a binary-detection algorithm in the <command>svn import</command> and <command>svn add</command> commands. These commands will make a good guess and then (possibly) set a binary <literal>svn:mime-type</literal> property on the file being added. (If Subversion guesses wrong, the user can always remove or hand-edit the property.)"
18131 #: ../source/book.xml:24692
18132 msgid "Versioned Modules"
18136 #: ../source/book.xml:24694
18137 msgid "Unlike CVS, a Subversion working copy is aware that it has checked out a module. That means that if somebody changes the definition of a module (e.g. adds or removes components), then a call to <command>svn update</command> will update the working copy appropriately, adding and removing components."
18141 #: ../source/book.xml:24699
18142 msgid "Subversion defines modules as a list of directories within a directory property: see <xref linkend=\"svn.advanced.externals\"/>."
18146 #: ../source/book.xml:24707
18147 msgid "Authentication"
18151 #: ../source/book.xml:24709
18152 msgid "With CVS's pserver, you are required to <quote>login</quote> to the server before any read or write operation—you sometimes even have to login for anonymous operations. With a Subversion repository using Apache <command>httpd</command> or <command>svnserve</command> 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."
18156 #: ../source/book.xml:24721
18157 msgid "As with CVS, Subversion still caches your credentials on disk (in your <filename>~/.subversion/auth/</filename> directory) unless you tell it not to by using the <option>--no-auth-cache</option> option."
18161 #: ../source/book.xml:24725
18162 msgid "The exception to this behavior, however, is in the case of accessing an <command>svnserve</command> server over an SSH tunnel, using the <literal>svn+ssh://</literal> URL scheme. In that case, the <command>ssh</command> program unconditionally demands authentication just to start the tunnel."
18166 #: ../source/book.xml:24736
18167 msgid "Converting a Repository from CVS to Subversion"
18171 #: ../source/book.xml:24738
18172 msgid "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."
18176 #: ../source/book.xml:24751
18177 msgid "The most popular (and likely the most mature) conversion tool is cvs2svn (<uri href=\"http://cvs2svn.tigris.org/\">http://cvs2svn.tigris.org/</uri>), a Python script originally created by members of Subversion's own development community. This tool is meant to run exactly once: it scans your CVS repository multiple times and attempts to deduce commits, branches, and tags as best it can. When it finishes, the result is a either a Subversion repository or a portable Subversion dumpfile representing your code's history. See the website for detailed instructions and caveats."
18181 #: ../source/book.xml:24769
18182 msgid "WebDAV and Autoversioning"
18186 #: ../source/book.xml:24771
18187 msgid "WebDAV is an extension to HTTP, and is growing more and more popular as a standard for file-sharing. Today's operating systems are becoming extremely Web-aware, and many now have built-in support for mounting <quote>shares</quote> exported by WebDAV servers."
18191 #: ../source/book.xml:24776
18192 msgid "If you use Apache as your Subversion network server, then to some extent you are also running a WebDAV server. This appendix gives some background on the nature of this protocol, how Subversion uses it, and how well Subversion interoperates with other software that is WebDAV-aware."
18196 #: ../source/book.xml:24786
18197 msgid "What is WebDAV?"
18201 #: ../source/book.xml:24788
18202 msgid "<firstterm>DAV</firstterm> stands for <quote>Distributed Authoring and Versioning</quote>. RFC 2518 defines a set of concepts and accompanying extension methods to HTTP 1.1 that make the web into a more universal read/write medium. The basic idea is that a WebDAV-compliant web server can act like a generic file server; clients can <quote>mount</quote> shared folders over HTTP that behave much like other network filesystems (such as NFS or SMB.)"
18206 #: ../source/book.xml:24796
18207 msgid "The tragedy, though, is that despite the acronym, the RFC specification doesn't actually describe any sort of version control. Basic WebDAV clients and servers assume only one version of each file or directory exists, and can be repeatedly overwritten."
18211 #: ../source/book.xml:24801
18212 msgid "Because RFC 2518 left out versioning concepts, another committee was left with the responsibility of writing RFC 3253 a few years later. The new RFC adds versioning concepts to WebDAV, placing the <quote>V</quote> back in <quote>DAV</quote> — hence the term <quote>DeltaV</quote>. WebDAV/DeltaV clients and servers are often called just <quote>DeltaV</quote> programs, since DeltaV implies the existence of basic WebDAV."
18216 #: ../source/book.xml:24809
18217 msgid "The original WebDAV standard has been widely successful. Every modern computer operating system has a general WebDAV client built-in (details to follow), and a number of popular standalone applications are also able to speak WebDAV— Microsoft Office, Dreamweaver, and Photoshop to name a few. On the server end, the Apache webserver has been able to provide WebDAV services since 1998 and is considered the de-facto open-source standard. There are several other commercial WebDAV servers available, including Microsoft's own IIS."
18221 #: ../source/book.xml:24818
18222 msgid "DeltaV, unfortunately, has not been so successful. It's very difficult to find any DeltaV clients or servers. The few that do exist are relatively unknown commercial products, and thus it's very difficult to test interoperability. It's not entirely clear as to why DeltaV has remained stagnant. Some argue that the specification is just too complex, others argue that while WebDAV's features have mass appeal (even the least technical users appreciate network file-sharing), version control features aren't interesting or necessary for most users. Finally, some have argued that DeltaV remains unpopular because there's still no open-source server product which implements it well."
18226 #: ../source/book.xml:24830
18227 msgid "When Subversion was still in its design phase, it seemed like a great idea to use Apache as a network server. It already had a module to provide WebDAV services. DeltaV was a relatively new specification. The hope was that the Subversion server module (<command>mod_dav_svn</command>) would eventually evolve into an open-source DeltaV reference implementation. Unfortunately, DeltaV has a very specific versioning model that doesn't quite line up with Subversion's model. Some concepts were mappable, others were not."
18231 #: ../source/book.xml:24839
18232 msgid "What does this mean, then?"
18236 #: ../source/book.xml:24840
18237 msgid "First, the Subversion client is not a fully-implemented DeltaV client. It needs certain types of things from the server that DeltaV itself cannot provide, and thus is largely dependent on a number of Subversion-specific HTTP <literal>REPORT</literal> requests that only <command>mod_dav_svn</command> understands."
18241 #: ../source/book.xml:24846
18242 msgid "Second, <command>mod_dav_svn</command> is not a fully-realized DeltaV server. Many portions of the DeltaV specification were irrelevant to Subversion, and thus left unimplemented."
18246 #: ../source/book.xml:24850
18247 msgid "There is still some debate in the developer community as to whether or not it's worthwhile to remedy either of these situations. It's fairly unrealistic to change Subversion's design to match DeltaV, so there's probably no way the client can ever learn to get everything it needs from a general DeltaV server. On the other hand, <command>mod_dav_svn</command><emphasis>could</emphasis> be further developed to implement all of DeltaV, but it's hard to find motivation to do so—there are almost no DeltaV clients to interoperate with."
18251 #: ../source/book.xml:24866
18252 msgid "Autoversioning"
18256 #: ../source/book.xml:24868
18257 msgid "While the Subversion client is not a full DeltaV client, nor the Subversion server a full DeltaV server, there's still a glimmer of WebDAV interoperability to be happy about: it's called autoversioning."
18261 #: ../source/book.xml:24872
18262 msgid "Autoversioning is an optional feature defined in the DeltaV standard. A typical DeltaV server will reject an ignorant WebDAV client attempting to do a <literal>PUT</literal> to a file that's under version control. To change a version-controlled file, the server expects a series of proper versioning requests: something like <literal>MKACTIVITY</literal>, <literal>CHECKOUT</literal>, <literal>PUT</literal>, <literal>CHECKIN</literal>. But if the DeltaV server supports autoversioning, then write-requests from basic WebDAV clients are accepted. The server behaves as if the client <emphasis>had</emphasis> issued the proper series of versioning requests, performing a commit under the hood. In other words, it allows a DeltaV server to interoperate with ordinary WebDAV clients that don't understand versioning."
18266 #: ../source/book.xml:24886
18267 msgid "Because so many operating systems already have integrated WebDAV clients, the use case for this feature can be incredibly appealing to administrators working with non-technical users: imagine an office of ordinary users running Microsoft Windows or Mac OS. Each user <quote>mounts</quote> the Subversion repository, which appears to be an ordinary network folder. They use the shared folder as they always do: open files, edit them, save them. Meanwhile, the server is automatically versioning everything. Any administrator (or knowledgeable user) can still use a Subversion client to search history and retrieve older versions of data."
18271 #: ../source/book.xml:24897
18272 msgid "This scenario isn't fiction: it's real and it works, as of Subversion 1.2 and later. To activate autoversioning in <command>mod_dav_svn</command>, use the <literal>SVNAutoversioning</literal> directive within the <filename>httpd.conf</filename> Location block, like so:"
18276 #: ../source/book.xml:24903
18278 msgid "\n<Location /repos>\n DAV svn\n SVNPath /path/to/repository\n SVNAutoversioning on\n</Location>\n"
18282 #: ../source/book.xml:24910
18283 msgid "When SVNAutoversioning is active, write requests from WebDAV clients result in automatic commits. A generic log message is auto-generated and attached to each revision."
18287 #: ../source/book.xml:24913
18288 msgid "Before activating this feature, however, understand what you're getting into. WebDAV clients tend to do <emphasis>many</emphasis> write requests, resulting in a huge number of automatically committed revisions. For example, when saving data, many clients will do a <literal>PUT</literal> of a 0-byte file (as a way of reserving a name) followed by another <literal>PUT</literal> with the real file data. The single file-write results in two separate commits. Also consider that many applications auto-save every few minutes, resulting in even more commits."
18292 #: ../source/book.xml:24923
18293 msgid "If you have a post-commit hook program that sends email, you may want to disable email generation either altogether, or on certain sections of the repository; it depends on whether you think the influx of emails will still prove to be valuable notifications or not. Also, a smart post-commit hook program can distinguish between a transaction created via autoversioning and one created through a normal <command>svn commit</command>. The trick is to look for a revision property named <literal>svn:autoversioned</literal>. If present, the commit was made by a generic WebDAV client."
18297 #: ../source/book.xml:24933
18298 msgid "Another feature that may be a useful complement for <literal>SVNAutoversioning</literal> comes from Apache's <literal>mod_mime</literal> module. If a WebDAV client adds a new file to the repository, there's no opportunity for the user to set the the <literal>svn:mime-type</literal> property. This might cause the file to appear as generic icon when viewed within a WebDAV shared folder, not having an association with any application. One remedy is to have a sysadmin (or other Subversion-knowledgeable person) check out a working copy and manually set the <literal>svn:mime-type</literal> property on necessary files. But there's potentially no end to such cleanup tasks. Instead, you can use the <literal>ModMimeUsePathInfo</literal> directive in your Subversion <literal><Location></literal> block:"
18302 #: ../source/book.xml:24948
18304 msgid "\n<Location /repos>\n DAV svn\n SVNPath /path/to/repository\n SVNAutoversioning on\n\n ModMimeUsePathInfo on\n\n</Location>\n"
18308 #: ../source/book.xml:24958
18309 msgid "This directive allows <literal>mod_mime</literal> to attempt automatic deduction of the mime-type on new files that enter the repository via autoversioning. The module looks at the file's named extension and possibly the contents as well; if the file matches some common patterns, then the the file's <literal>svn:mime-type</literal> property will be set automatically."
18313 #: ../source/book.xml:24971
18314 msgid "Client Interoperability"
18318 #: ../source/book.xml:24973
18319 msgid "All WebDAV clients fall into one of three categories—standalone applications, file-explorer extensions, or filesystem implementations. These categories broadly define the types of WebDAV functionality available to users. <xref linkend=\"svn.webdav.clients.tbl-1\"/> gives our categorization and a quick description of some common pieces of WebDAV-enabled software. More details about these software offerings, as well as their general category, can be found in the sections that follow."
18323 #: ../source/book.xml:24984
18324 msgid "Common WebDAV Clients"
18328 #: ../source/book.xml:24989
18333 #: ../source/book.xml:24990
18338 #: ../source/book.xml:24991
18343 #: ../source/book.xml:24992
18348 #: ../source/book.xml:24993
18353 #: ../source/book.xml:24999
18354 msgid "Adobe Photoshop"
18358 #: ../source/book.xml:25000 ../source/book.xml:25009 ../source/book.xml:25018 ../source/book.xml:25026 ../source/book.xml:25035
18359 msgid "Standalone WebDAV application"
18363 #: ../source/book.xml:25001 ../source/book.xml:25011 ../source/book.xml:25012 ../source/book.xml:25019 ../source/book.xml:25020 ../source/book.xml:25021 ../source/book.xml:25027 ../source/book.xml:25036 ../source/book.xml:25046 ../source/book.xml:25057 ../source/book.xml:25066 ../source/book.xml:25074 ../source/book.xml:25082 ../source/book.xml:25091 ../source/book.xml:25103
18368 #: ../source/book.xml:25004
18369 msgid "Image editing software, allowing direct opening from, and writing to, WebDAV URLs"
18373 #: ../source/book.xml:25008
18378 #: ../source/book.xml:25013
18379 msgid "Command-line WebDAV client supporting file transfer, tree, and locking operations"
18383 #: ../source/book.xml:25017
18384 msgid "DAV Explorer"
18388 #: ../source/book.xml:25022
18389 msgid "Java GUI tool for exploring WebDAV shares"
18393 #: ../source/book.xml:25025
18394 msgid "Macromedia Dreamweaver"
18398 #: ../source/book.xml:25030
18399 msgid "Web production software able to directly read from and write to WebDAV URLs"
18403 #: ../source/book.xml:25034
18404 msgid "Microsoft Office"
18408 #: ../source/book.xml:25039
18409 msgid "Office productivity suite with several components able to directly read from and write to WebDAV URLs"
18413 #: ../source/book.xml:25044 ../source/book.xml:25211
18414 msgid "Microsoft Web Folders"
18418 #: ../source/book.xml:25045 ../source/book.xml:25054 ../source/book.xml:25063
18419 msgid "File-explorer WebDAV extension"
18423 #: ../source/book.xml:25049
18424 msgid "GUI file explorer program able to perform tree operations on a WebDAV share"
18428 #: ../source/book.xml:25053
18429 msgid "GNOME Nautilus"
18433 #: ../source/book.xml:25058 ../source/book.xml:25067
18434 msgid "GUI file explorer able to perform tree operations on a WebDAV share"
18438 #: ../source/book.xml:25062
18439 msgid "KDE Konqueror"
18443 #: ../source/book.xml:25071 ../source/book.xml:25340
18448 #: ../source/book.xml:25072 ../source/book.xml:25081 ../source/book.xml:25090 ../source/book.xml:25100 ../source/book.xml:25309
18449 msgid "WebDAV filesystem implementation"
18453 #: ../source/book.xml:25076
18454 msgid "Operating system has built-in support for mounting WebDAV shares."
18458 #: ../source/book.xml:25080
18459 msgid "Novell NetDrive"
18463 #: ../source/book.xml:25085
18464 msgid "Drive-mapping program for assigning Windows drive letters to a mounted remote WebDAV share"
18468 #: ../source/book.xml:25089
18469 msgid "SRT WebDrive"
18473 #: ../source/book.xml:25094
18474 msgid "File transfer software which, among other things, allows the assignment of Windows drive letters to a mounted remote WebDAV share"
18478 #: ../source/book.xml:25099
18483 #: ../source/book.xml:25104
18484 msgid "Linux file system driver that allows you to mount a WebDAV share"
18488 #: ../source/book.xml:25113
18489 msgid "Standalone WebDAV applications"
18493 #: ../source/book.xml:25115
18494 msgid "A WebDAV application is a program which speakes WebDAV protocols with a WebDAV server. We'll cover some of the most popular programs with this kind of WebDAV support."
18498 #: ../source/book.xml:25121
18499 msgid "Microsoft Office, Dreamweaver, Photoshop"
18503 #: ../source/book.xml:25126
18504 msgid "WebDAV support was removed from Microsoft Access for some reason, but exists in the rest of the Office suite."
18508 #: ../source/book.xml:25123
18509 msgid "On Windows, there are several well-known applications that contain integrated WebDAV client functionality, such as Microsoft's Office, <placeholder-1/> Adobe's Photoshop, and Macromedia's Dreamweaver programs. They're able to directly open and save to URLs, and tend to make heavy use of WebDAV locks when editing a file."
18513 #: ../source/book.xml:25132
18514 msgid "Note that while many of these programs also exist for the Mac OS X, they do not appear to support WebDAV directly on that platform. In fact, on Mac OS X, the <guimenu>File->Open</guimenu> dialog box doesn't allow one to type a path or URL at all. It's likely that the WebDAV features were deliberately left out of Macintosh versions of these programs, since OS X already provides such excellent low-level filesystem support for WebDAV."
18518 #: ../source/book.xml:25144
18519 msgid "Cadaver, DAV Explorer"
18523 #: ../source/book.xml:25146
18524 msgid "Cadaver is a bare-bones Unix commandline program for browsing and changing WebDAV shares. Like the Subversion client, it uses the neon HTTP library—not surprisingly, since both neon and cadaver are written by the same author. Cadaver is free software (GPL license) and is available at <uri href=\"http://www.webdav.org/cadaver/\">http://www.webdav.org/cadaver/</uri>."
18528 #: ../source/book.xml:25153
18529 msgid "Using cadaver is similar to using a commandline FTP program, and thus it's extremely useful for basic WebDAV debugging. It can be used to upload or download files in a pinch, and also to examine properties, and to copy, move, lock or unlock files:"
18533 #: ../source/book.xml:25158
18535 msgid "\n$ cadaver http://host/repos\ndav:/repos/> ls\nListing collection `/repos/': succeeded.\nColl: > foobar 0 May 10 16:19\n > playwright.el 2864 May 4 16:18\n > proofbypoem.txt 1461 May 5 15:09\n > westcoast.jpg 66737 May 5 15:09\n\ndav:/repos/> put README\nUploading README to `/repos/README':\nProgress: [=============================>] 100.0% of 357 bytes succeeded.\n\ndav:/repos/> get proofbypoem.txt\nDownloading `/repos/proofbypoem.txt' to proofbypoem.txt:\nProgress: [=============================>] 100.0% of 1461 bytes succeeded.\n"
18539 #: ../source/book.xml:25175
18540 msgid "DAV Explorer is another standalone WebDAV client, written in Java. It's under a free Apache-like license and is available at <uri href=\"http://www.ics.uci.edu/~webdav/\">http://www.ics.uci.edu/~webdav/</uri>. DAV Explorer does everything cadaver does, but has the advantages of being portable and being a more user-friendly GUI application. It's also one of the first clients to support the new WebDAV Access Control Protocol (RFC 3744)."
18544 #: ../source/book.xml:25182
18545 msgid "Of course, DAV Explorer's ACL support is useless in this case, since <command>mod_dav_svn</command> doesn't support it. The fact that both Cadaver and DAV Explorer support some limited DeltaV commands isn't particularly useful either, since they don't allow <literal>MKACTIVITY</literal> requests. But it's not relevant anyway; we're assuming all of these clients are operating against an autoversioning repository."
18549 #: ../source/book.xml:25195
18550 msgid "File-explorer WebDAV extensions"
18554 #: ../source/book.xml:25197
18555 msgid "Some popular file explorer GUI programs support WebDAV extensions which allow a user to browse a DAV share as if it was just another directory on the local computer, and to perform basic tree editing operations on the items in that share. For example, Windows Explorer is able to browse a WebDAV server as a <quote>network place</quote>. Users can drag files to and from the desktop, or can rename, copy, or delete files in the usual way. But because it's only a feature of the file-explorer, the DAV share isn't visible to ordinary applications. All DAV interaction must happen through the explorer interface."
18559 #: ../source/book.xml:25213
18560 msgid "Microsoft was one of the original backers of the WebDAV specification, and first started shipping a client in Windows 98, known as <quote>Web Folders</quote>. This client was also shipped in Windows NT4 and 2000."
18564 #: ../source/book.xml:25217
18565 msgid "The original Web Folders client was an extension to Explorer, the main GUI program used to browse filesystems. It works well enough. In Windows 98, the feature might need to be explicitly installed if Web Folders aren't already visible inside <quote>My Computer</quote>. In Windows 2000, simply add a new <quote>network place</quote>, enter the URL, and the WebDAV share will pop up for browsing."
18569 #: ../source/book.xml:25224
18570 msgid "With the release of Windows XP, Microsoft started shipping a new implementation of Web Folders, known as the <quote>WebDAV mini-redirector</quote>. The new implementation is a filesystem-level client, allowing WebDAV shares to be mounted as drive letters. Unfortunately, this implementation is incredibly buggy. The client usually tries to convert http URLs (<literal>http://host/repos</literal>) into UNC share notation (<literal>\\\\host\\repos</literal>); it also often tries to use Windows Domain authentication to respond to basic-auth HTTP challenges, sending usernames as <literal>HOST\\username</literal>. These interoperability problems are severe and documented in numerous places around the web, to the frustration of many users. Even Greg Stein, the original author of Apache's WebDAV module, recommends against trying to use XP Web Folders against an Apache server."
18574 #: ../source/book.xml:25240
18575 msgid "It turns out that the original <quote>Explorer-only</quote> Web Folders implementation isn't dead in XP, it's just buried. It's still possible to find it by using this technique:"
18579 #: ../source/book.xml:25246
18580 msgid "Go to 'Network Places'."
18584 #: ../source/book.xml:25249
18585 msgid "Add a new network place."
18589 #: ../source/book.xml:25252
18590 msgid "When prompted, enter the URL of the repository, but <emphasis>include a port number</emphasis> in the URL. For example, <literal>http://host/repos</literal> would be entered as <literal>http://host:80/repos</literal> instead."
18594 #: ../source/book.xml:25259
18595 msgid "Respond to any authentication prompts."
18599 #: ../source/book.xml:25262
18600 msgid "There are a number of other rumored workarounds to the problems, but none of them seem to work on all versions and patchlevels of Windows XP. In our tests, only the previous algorithm seems to work consistently on every system. The general consensus of the WebDAV community is that you should avoid the new Web Folders implementation and use the old one instead, and that if you need a real filesystem-level client for Windows XP, then use a third-party program like WebDrive or NetDrive."
18604 #: ../source/book.xml:25271
18605 msgid "A final tip: if you're attempting to use XP Web Folders, make sure you have the absolute latest version from Microsoft. For example, Microsoft released a bug-fixed version in January 2005, available at <uri href=\"http://support.microsoft.com/?kbid=892211\">http://support.microsoft.com/?kbid=892211</uri>. In particular, this release is known to fix a bug whereby browsing a DAV share shows an unexpected infinite recursion."
18609 #: ../source/book.xml:25283
18610 msgid "Nautilus, Konqueror"
18614 #: ../source/book.xml:25285
18615 msgid "Nautilus is the official file manager/browser for the GNOME desktop (<uri href=\"http://www.gnome.org\">http://www.gnome.org</uri>), and Konqueror is the manager/browser for the KDE desktop (<uri href=\"http://www.kde.org\">http://www.kde.org</uri>). Both of these applications have an explorer-level WebDAV client built-in, and operate just fine against an autoversioning repository."
18619 #: ../source/book.xml:25290
18620 msgid "In GNOME's Nautilus, from the <guimenu>File menu</guimenu>, select <guimenuitem>Open location</guimenuitem> and enter the URL. The repository should then be displayed like any other filesystem."
18624 #: ../source/book.xml:25294
18625 msgid "In KDE's Konqueror, you need to use the <literal>webdav://</literal> scheme when entering the URL in the location bar. If you enter an <literal>http://</literal> URL, Konqueror will behave like an ordinary web browser. You'll likely see the generic HTML directory listing produced by <command>mod_dav_svn</command>. By entering <literal>webdav://host/repos</literal> instead of <literal>http://host/repos</literal>, Konqueror becomes a WebDAV client and displays the repository as a filesystem."
18629 #: ../source/book.xml:25311
18630 msgid "The WebDAV filesystem implementation is arguably the best sort of WebDAV client. It's implemented as a low-level filesystem module, typically within the operating system's kernel. This means that the DAV share is mounted like any other network filesystem, similar to mounting an NFS share on Unix, or attaching an SMB share as drive letter in Windows. As a result, this sort of client provides completely transparent read/write WebDAV access to all programs. Applications aren't even aware that WebDAV requests are happening."
18634 #: ../source/book.xml:25324
18635 msgid "WebDrive, NetDrive"
18639 #: ../source/book.xml:25326
18640 msgid "Both WebDrive and NetDrive are excellent commercial products which allow a WebDAV share to be attached as drive letters in Windows. We've had nothing but success with these products. At the time of writing, WebDrive can be purchased from South River Technologies (<uri href=\"http://www.southrivertech.com\">http://www.southrivertech.com</uri>). NetDrive ships with Netware, is free of charge, and can be found by searching the web for <quote>netdrive.exe</quote>. Though it is freely available online, users are required to have a Netware license. (If any of that sounds odd to you, you're not alone. See this page on Novell's website: <uri href=\"http://www.novell.com/coolsolutions/qna/999.html\">http://www.novell.com/coolsolutions/qna/999.html</uri>)"
18644 #: ../source/book.xml:25342
18645 msgid "Apple's OS X operating system has an integrated filesystem-level WebDAV client. From the Finder, select the <guimenuitem>Connect to Server</guimenuitem> item from the <guimenu>Go menu</guimenu>. Enter a WebDAV URL, and it appears as a disk on the desktop, just like any other mounted volume. You can also mount a WebDAV share from the Darwin terminal by using the <literal>webdav</literal> filesystem type with the <command>mount</command> command:"
18649 #: ../source/book.xml:25350
18651 msgid "\n$ mount -t webdav http://svn.example.com/repos/project /some/mountpoint\n$\n"
18655 #: ../source/book.xml:25354
18656 msgid "Note that if your <command>mod_dav_svn</command> is older than version 1.2, OS X will refuse to mount the share as read-write; it will appear as read-only. This is because OS X insists on locking support for read-write shares, and the ability to lock files first appeared in Subversion 1.2."
18660 #: ../source/book.xml:25360
18661 msgid "One more word of warning: OS X's WebDAV client can sometimes be overly sensitive to HTTP redirects. If OS X is unable to mount the repository at all, you may need to enable the BrowserMatch directive in the Apache server's <filename>httpd.conf</filename>:"
18665 #: ../source/book.xml:25365
18667 msgid "\nBrowserMatch \"^WebDAVFS/1.[012]\" redirect-carefully\n"
18671 #: ../source/book.xml:25372
18672 msgid "Linux davfs2"
18676 #: ../source/book.xml:25374
18677 msgid "Linux davfs2 is a filesystem module for the Linux kernel, whose development is located at <uri href=\"http://dav.sourceforge.net/\">http://dav.sourceforge.net/</uri>. Once installed, a WebDAV network share can be mounted with the usual Linux mount command:"
18681 #: ../source/book.xml:25378
18683 msgid "\n$ mount.davfs http://host/repos /mnt/dav\n"
18687 #: ../source/book.xml:25392
18688 msgid "Third Party Tools"
18692 #: ../source/book.xml:25394
18693 msgid "Subversion's modular design (covered in <xref linkend=\"svn.developer.layerlib\"/>) and the availability of language bindings (as described in <xref linkend=\"svn.developer.usingapi.otherlangs\"/>) make it a likely candidate for use as an extension or backend to other pieces of software. For a listing of many third-party tools that are using Subversion functionality under-the-hood, check out the Links page on the Subversion website (<uri href=\"http://subversion.tigris.org/project_links.html\">http://subversion.tigris.org/project_links.html</uri>)."
18697 #: ../source/book.xml:25408
18702 #: ../source/book.xml:25410
18704 msgid "\n\nCopyright (c) 2002-2007\nBen Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato. \n\nThis work is licensed under the Creative Commons Attribution License.\nTo view a copy of this license, visit\nhttp://creativecommons.org/licenses/by/2.0/ or send a letter to\nCreative Commons, 559 Nathan Abbott Way, Stanford, California 94305,\nUSA.\n\nA summary of the license is given below, followed by the full legal\ntext.\n\n--------------------------------------------------------------------\n\nYou are free:\n\n * to copy, distribute, display, and perform the work\n * to make derivative works\n * to make commercial use of the work\n\nUnder the following conditions:\n\t\nAttribution. You must give the original author credit.\n\n * For any reuse or distribution, you must make clear to others the\n license terms of this work.\n\n * Any of these conditions can be waived if you get permission from\n the author.\n\nYour fair use and other rights are in no way affected by the above.\n\nThe above is a summary of the full license below.\n\n====================================================================\n\nCreative Commons Legal Code\nAttribution 2.0\n\nCREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE\nLEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN\nATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS\nINFORMATION ON AN \"AS-IS\" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES\nREGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR\nDAMAGES RESULTING FROM ITS USE.\n\nLicense\n\nTHE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS\nCREATIVE COMMONS PUBLIC LICENSE (\"CCPL\" OR \"LICENSE\"). THE WORK IS\nPROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE\nWORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS\nPROHIBITED.\n\nBY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND\nAGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS\nYOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF\nSUCH TERMS AND CONDITIONS.\n\n1. Definitions\n\n a. \"Collective Work\" means a work, such as a periodical issue,\n anthology or encyclopedia, in which the Work in its entirety in\n unmodified form, along with a number of other contributions,\n constituting separate and independent works in themselves, are\n assembled into a collective whole. A work that constitutes a\n Collective Work will not be considered a Derivative Work (as\n defined below) for the purposes of this License.\n\n b. \"Derivative Work\" means a work based upon the Work or upon the\n Work and other pre-existing works, such as a translation,\n musical arrangement, dramatization, fictionalization, motion\n picture version, sound recording, art reproduction, abridgment,\n condensation, or any other form in which the Work may be recast,\n transformed, or adapted, except that a work that constitutes a\n Collective Work will not be considered a Derivative Work for the\n purpose of this License. For the avoidance of doubt, where the\n Work is a musical composition or sound recording, the\n synchronization of the Work in timed-relation with a moving\n image (\"synching\") will be considered a Derivative Work for the\n purpose of this License.\n\n c. \"Licensor\" means the individual or entity that offers the Work\n under the terms of this License.\n\n d. \"Original Author\" means the individual or entity who created the Work.\n\n e. \"Work\" means the copyrightable work of authorship offered under\n the terms of this License.\n\n f. \"You\" means an individual or entity exercising rights under this\n License who has not previously violated the terms of this\n License with respect to the Work, or who has received express\n permission from the Licensor to exercise rights under this\n License despite a previous violation.\n\n2. Fair Use Rights. Nothing in this license is intended to reduce,\n limit, or restrict any rights arising from fair use, first sale or\n other limitations on the exclusive rights of the copyright owner\n under copyright law or other applicable laws.\n\n3. License Grant. Subject to the terms and conditions of this License,\n Licensor hereby grants You a worldwide, royalty-free,\n non-exclusive, perpetual (for the duration of the applicable\n copyright) license to exercise the rights in the Work as stated\n below:\n\n a. to reproduce the Work, to incorporate the Work into one or more\n Collective Works, and to reproduce the Work as incorporated in\n the Collective Works;\n\n b. to create and reproduce Derivative Works;\n\n c. to distribute copies or phonorecords of, display publicly,\n perform publicly, and perform publicly by means of a digital\n audio transmission the Work including as incorporated in\n Collective Works;\n\n d. to distribute copies or phonorecords of, display publicly,\n perform publicly, and perform publicly by means of a digital\n audio transmission Derivative Works.\n\n e.\n\n For the avoidance of doubt, where the work is a musical composition:\n\n i. Performance Royalties Under Blanket Licenses. Licensor\n waives the exclusive right to collect, whether\n individually or via a performance rights society\n (e.g. ASCAP, BMI, SESAC), royalties for the public\n performance or public digital performance (e.g. webcast)\n of the Work.\n\n ii. Mechanical Rights and Statutory Royalties. Licensor waives\n the exclusive right to collect, whether individually or\n via a music rights agency or designated agent (e.g. Harry\n Fox Agency), royalties for any phonorecord You create from\n the Work (\"cover version\") and distribute, subject to the\n compulsory license created by 17 USC Section 115 of the US\n Copyright Act (or the equivalent in other jurisdictions).\n\n f. Webcasting Rights and Statutory Royalties. For the avoidance of\n doubt, where the Work is a sound recording, Licensor waives the\n exclusive right to collect, whether individually or via a\n performance-rights society (e.g. SoundExchange), royalties for\n the public digital performance (e.g. webcast) of the Work,\n subject to the compulsory license created by 17 USC Section 114\n of the US Copyright Act (or the equivalent in other\n jurisdictions).\n\nThe above rights may be exercised in all media and formats whether now\nknown or hereafter devised. The above rights include the right to make\nsuch modifications as are technically necessary to exercise the rights\nin other media and formats. All rights not expressly granted by\nLicensor are hereby reserved.\n\n4. Restrictions.The license granted in Section 3 above is expressly\n made subject to and limited by the following restrictions:\n\n a. You may distribute, publicly display, publicly perform, or\n publicly digitally perform the Work only under the terms of this\n License, and You must include a copy of, or the Uniform Resource\n Identifier for, this License with every copy or phonorecord of\n the Work You distribute, publicly display, publicly perform, or\n publicly digitally perform. You may not offer or impose any\n terms on the Work that alter or restrict the terms of this\n License or the recipients' exercise of the rights granted\n hereunder. You may not sublicense the Work. You must keep intact\n all notices that refer to this License and to the disclaimer of\n warranties. You may not distribute, publicly display, publicly\n perform, or publicly digitally perform the Work with any\n technological measures that control access or use of the Work in\n a manner inconsistent with the terms of this License\n Agreement. The above applies to the Work as incorporated in a\n Collective Work, but this does not require the Collective Work\n apart from the Work itself to be made subject to the terms of\n this License. If You create a Collective Work, upon notice from\n any Licensor You must, to the extent practicable, remove from\n the Collective Work any reference to such Licensor or the\n Original Author, as requested. If You create a Derivative Work,\n upon notice from any Licensor You must, to the extent\n practicable, remove from the Derivative Work any reference to\n such Licensor or the Original Author, as requested.\n\n b. If you distribute, publicly display, publicly perform, or\n publicly digitally perform the Work or any Derivative Works or\n Collective Works, You must keep intact all copyright notices for\n the Work and give the Original Author credit reasonable to the\n medium or means You are utilizing by conveying the name (or\n pseudonym if applicable) of the Original Author if supplied; the\n title of the Work if supplied; to the extent reasonably\n practicable, the Uniform Resource Identifier, if any, that\n Licensor specifies to be associated with the Work, unless such\n URI does not refer to the copyright notice or licensing\n information for the Work; and in the case of a Derivative Work,\n a credit identifying the use of the Work in the Derivative Work\n (e.g., \"French translation of the Work by Original Author,\" or\n \"Screenplay based on original Work by Original Author\"). Such\n credit may be implemented in any reasonable manner; provided,\n however, that in the case of a Derivative Work or Collective\n Work, at a minimum such credit will appear where any other\n comparable authorship credit appears and in a manner at least as\n prominent as such other comparable authorship credit.\n\n5. Representations, Warranties and Disclaimer\n\nUNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING,\nLICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR\nWARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED,\nSTATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF\nTITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE,\nNONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY,\nOR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT\nDISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED\nWARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.\n\n6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY\n APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY\n LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE\n OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE\n WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\n DAMAGES.\n\n7. Termination\n\n a. This License and the rights granted hereunder will terminate\n automatically upon any breach by You of the terms of this\n License. Individuals or entities who have received Derivative\n Works or Collective Works from You under this License, however,\n will not have their licenses terminated provided such\n individuals or entities remain in full compliance with those\n licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any\n termination of this License.\n\n b. Subject to the above terms and conditions, the license granted\n here is perpetual (for the duration of the applicable copyright\n in the Work). Notwithstanding the above, Licensor reserves the\n right to release the Work under different license terms or to\n stop distributing the Work at any time; provided, however that\n any such election will not serve to withdraw this License (or\n any other license that has been, or is required to be, granted\n under the terms of this License), and this License will continue\n in full force and effect unless terminated as stated above.\n\n8. Miscellaneous\n\n a. Each time You distribute or publicly digitally perform the Work\n or a Collective Work, the Licensor offers to the recipient a\n license to the Work on the same terms and conditions as the\n license granted to You under this License.\n\n b. Each time You distribute or publicly digitally perform a\n Derivative Work, Licensor offers to the recipient a license to\n the original Work on the same terms and conditions as the\n license granted to You under this License.\n\n c. If any provision of this License is invalid or unenforceable\n under applicable law, it shall not affect the validity or\n enforceability of the remainder of the terms of this License,\n and without further action by the parties to this agreement,\n such provision shall be reformed to the minimum extent necessary\n to make such provision valid and enforceable.\n\n d. No term or provision of this License shall be deemed waived and\n no breach consented to unless such waiver or consent shall be in\n writing and signed by the party to be charged with such waiver\n or consent.\n\n e. This License constitutes the entire agreement between the\n parties with respect to the Work licensed here. There are no\n understandings, agreements or representations with respect to\n the Work not specified here. Licensor shall not be bound by any\n additional provisions that may appear in any communication from\n You. This License may not be modified without the mutual written\n agreement of the Licensor and You.\n\nCreative Commons is not a party to this License, and makes no warranty\nwhatsoever in connection with the Work. Creative Commons will not be\nliable to You or any party on any legal theory for any damages\nwhatsoever, including without limitation any general, special,\nincidental or consequential damages arising in connection to this\nlicense. Notwithstanding the foregoing two (2) sentences, if Creative\nCommons has expressly identified itself as the Licensor hereunder, it\nshall have all rights and obligations of Licensor.\n\nExcept for the limited purpose of indicating to the public that the\nWork is licensed under the CCPL, neither party will use the trademark\n\"Creative Commons\" or any related trademark or logo of Creative\nCommons without the prior written consent of Creative Commons. Any\npermitted use will be in compliance with Creative Commons'\nthen-current trademark usage guidelines, as may be published on its\nwebsite or otherwise made available upon request from time to time.\n\nCreative Commons may be contacted at http://creativecommons.org/.\n\n====================================================================\n"
18707 #. Put one translator per line, in the form of NAME <EMAIL>, YEAR1, YEAR2.
18709 #: ../source/book.xml:0
18710 msgid "translator-credits"