cvs-crossover-guide.html revision 251881
1251881Speter<!-- 2251881Speter 3251881Speter Licensed to the Apache Software Foundation (ASF) under one 4251881Speter or more contributor license agreements. See the NOTICE file 5251881Speter distributed with this work for additional information 6251881Speter regarding copyright ownership. The ASF licenses this file 7251881Speter to you under the Apache License, Version 2.0 (the 8251881Speter "License"); you may not use this file except in compliance 9251881Speter with the License. You may obtain a copy of the License at 10251881Speter 11251881Speter http://www.apache.org/licenses/LICENSE-2.0 12251881Speter 13251881Speter Unless required by applicable law or agreed to in writing, 14251881Speter software distributed under the License is distributed on an 15251881Speter "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16251881Speter KIND, either express or implied. See the License for the 17251881Speter specific language governing permissions and limitations 18251881Speter under the License. 19251881Speter 20251881Speter--> 21251881Speter<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" 22251881Speter "http://www.w3.org/TR/html4/strict.dtd"> 23251881Speter<html> 24251881Speter<head> 25251881Speter<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 26251881Speter<title>CVS to SVN Crossover Guide</title> 27251881Speter<style type="text/css"> 28251881Speterbody { 29251881Speter font-family: sans-serif; 30251881Speter} 31251881Speterh1 { 32251881Speter text-align: center; 33251881Speter} 34251881Speterh2 { 35251881Speter background: #b0c0f0; 36251881Speter margin: 0; 37251881Speter} 38251881Speter.h2 { 39251881Speter border-left: 4px #b0c0f0 solid; 40251881Speter margin-bottom: 2em; 41251881Speter} 42251881Speterhr { 43251881Speter height: 1px; 44251881Speter width: 80%; 45251881Speter} 46251881Speterp, h3, dl { 47251881Speter padding-left: 1em; 48251881Speter} 49251881Speterdd { 50251881Speter margin-left: 2em; 51251881Speter} 52251881Speter.sidebyside { 53251881Speter padding: 0 2em; 54251881Speter width: 100%; 55251881Speter font-size: 80%; 56251881Speter} 57251881Speter.sidebyside th, .sidebyside td { 58251881Speter width: 50%; 59251881Speter border-width: 0 1px 2px 0; 60251881Speter border-style: solid; 61251881Speter border-color: black; 62251881Speter background: #b0c0f0; 63251881Speter vertical-align: top; 64251881Speter} 65251881Speter.sidebyside th { 66251881Speter text-align: center; 67251881Speter background: #90a0d0; 68251881Speter} 69251881Speter.bookref { 70251881Speter font-size: 80%; 71251881Speter} 72251881Speter</style> 73251881Speter</head> 74251881Speter 75251881Speter<body> 76251881Speter 77251881Speter<h1>CVS to SVN Crossover Guide</h1> 78251881Speter 79251881Speter<!-- ==================================================================== --> 80251881Speter<div class="h2"> 81251881Speter<h2>Purpose</h2> 82251881Speter 83251881Speter<p>This document provides an alternate method of learning Subversion. 84251881Speter Many users dislike learning new technology via a theoretical "top 85251881Speter down" approach, as provided by the <a 86251881Speter href="http://svnbook.red-bean.com">Subversion Book</a>. Instead, 87251881Speter this document presents Subversion from the "bottom up": it shows a 88251881Speter CVS command or task, and then shows the equivalent task in 89251881Speter Subversion (along with relevant book links.) It's essentially a 90251881Speter re-indexing of topics covered by the book, keyed on CVS tasks.</p> 91251881Speter 92251881Speter</div> 93251881Speter 94251881Speter<!-- ==================================================================== --> 95251881Speter<div class="h2"> 96251881Speter<h2>Table of Contents</h2> 97251881Speter 98251881Speter<h3>Setup</h3> 99251881Speter<ul> 100251881Speter <li><a href="#repos_creation">Repository creation</a></li> 101251881Speter <li><a href="#import">Importing data</a></li> 102251881Speter <li><a href="#installing">Installing a server</a></li> 103251881Speter <li><a href="#authenticating">Authenticating to a server</a></li> 104251881Speter <li><a href="#browsing">Browsing a repository</a></li> 105251881Speter <li><a href="#checkingout">Checking out a working copy</a></li> 106251881Speter</ul> 107251881Speter 108251881Speter<h3>Basic Work Cycle</h3> 109251881Speter<ul> 110251881Speter <li><a href="#changeditems">Seeing locally changed items</a></li> 111251881Speter <li><a href="#outofdate">Seeing out-of-date items</a></li> 112251881Speter <li><a href="#scheduling">Scheduling additions or deletions</a></li> 113251881Speter <li><a href="#copying">Copying and moving</a></li> 114251881Speter <li>Undoing local changes</li> 115251881Speter <li>Updating and committing</li> 116251881Speter <li>Resolving conflicts</li> 117251881Speter <li>Adding a binary file</li> 118251881Speter <li>Using native line-endings</li> 119251881Speter</ul> 120251881Speter 121251881Speter<h3>Examining history</h3> 122251881Speter<ul> 123251881Speter <li>Seeing history of an item</li> 124251881Speter <li>Comparing two versions of an item</li> 125251881Speter</ul> 126251881Speter 127251881Speter<h3>Branching/Tagging/Merging</h3> 128251881Speter<ul> 129251881Speter <li>Creating a branch</li> 130251881Speter <li>Moving a working copy to a branch</li> 131251881Speter <li>Finding the beginning of a branch</li> 132251881Speter <li>Porting a single change</li> 133251881Speter <li>Merging a whole branch</li> 134251881Speter <li>Reverting a committed change</li> 135251881Speter <li>Resurrecting deleted items</li> 136251881Speter <li>Creating a tag</li> 137251881Speter <li>Tweaking a tag</li> 138251881Speter <li>Seeing all tags</li> 139251881Speter <li>Comparing two tags</li> 140251881Speter <li>Seeing logs between two tags</li> 141251881Speter</ul> 142251881Speter 143251881Speter<h3>Other tasks</h3> 144251881Speter<ul> 145251881Speter <li>Using modules</li> 146251881Speter <li>Line endings and keywords</li> 147251881Speter</ul> 148251881Speter 149251881Speter</div> 150251881Speter 151251881Speter<!-- ==================================================================== --> 152251881Speter<div class="h2"> 153251881Speter<h2 id="repos_creation">Repository creation</h2> 154251881Speter 155251881Speter<p>Create a new repository for holding versioned data.</p> 156251881Speter 157251881Speter<table class="sidebyside"> 158251881Speter<tr> 159251881Speter <th>CVS</th> 160251881Speter <th>Subversion</th> 161251881Speter</tr> 162251881Speter<tr> 163251881Speter <td> 164251881Speter <dl> 165251881Speter <dt>Commands:</dt> 166251881Speter <dd><tt>$ cvs -d /usr/local/repos init</tt></dd> 167251881Speter 168251881Speter <dt>Explanation:</dt> 169251881Speter <dd>Creates a new directory <tt>repos</tt> ready to hold RCS 170251881Speter files and config scripts.</dd> 171251881Speter </dl> 172251881Speter </td> 173251881Speter <td> 174251881Speter <dl> 175251881Speter <dt>Commands:</dt> 176251881Speter <dd><tt>$ svnadmin create /usr/local/repos</tt></dd> 177251881Speter 178251881Speter <dt>Explanation:</dt> 179251881Speter <dd>Creates a new directory <tt>repos</tt> containing BerkeleyDB 180251881Speter files and config scripts.</dd> 181251881Speter </dl> 182251881Speter </td> 183251881Speter</tr> 184251881Speter</table> 185251881Speter 186251881Speter<dl class="bookref"> 187251881Speter <dt>Book References:</dt> 188251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch05s02.html">Repository Creation and Configuration</a></dd> 189251881Speter</dl> 190251881Speter 191251881Speter</div> 192251881Speter 193251881Speter<!-- ==================================================================== --> 194251881Speter<div class="h2"> 195251881Speter<h2 id="import">Importing data</h2> 196251881Speter 197251881Speter<p>Populate a new repository with initial data. Assuming that you 198251881Speter have a tree of code in the local directory <tt>myproj/</tt>, and 199251881Speter you want to move this tree into the repository.</p> 200251881Speter 201251881Speter<table class="sidebyside"> 202251881Speter<tr> 203251881Speter <th>CVS</th> 204251881Speter <th>Subversion</th> 205251881Speter</tr> 206251881Speter<tr> 207251881Speter <td> 208251881Speter <dl> 209251881Speter <dt>Commands:</dt> 210251881Speter <dd><tt>$ cd myproj</tt></dd> 211251881Speter <dd><tt>$ cvs -d /usr/local/repos import myproj/ none start</tt></dd> 212251881Speter 213251881Speter <dt>Explanation:</dt> 214251881Speter 215251881Speter <dd>This copies the contents of the current working directory to 216251881Speter a new directory (<tt>myproj</tt>) in the CVS repository. The 217251881Speter CVS repository now contains a directory <tt>/myproj/</tt> at the 218251881Speter top level.</dd> 219251881Speter 220251881Speter </dl> 221251881Speter </td> 222251881Speter <td> 223251881Speter <dl> 224251881Speter <dt>Commands:</dt> 225251881Speter <dd><tt>$ svn mkdir file:///usr/local/repos/tags</tt></dd> 226251881Speter <dd><tt>$ svn mkdir file:///usr/local/repos/branches</tt></dd> 227251881Speter <dd><tt>$ svn import myproj/ file:///usr/local/repos/trunk</tt></dd> 228251881Speter 229251881Speter <dt>Explanation:</dt> 230251881Speter 231251881Speter <dd>Though not strictly required, we deliberately create 232251881Speter <tt>/tags</tt> and <tt>/branches</tt> top-level directories in 233251881Speter the repository, to hold tags and branches later on. Then we 234251881Speter import the contents of the local <tt>myproj/</tt> directory into 235251881Speter a newly created <tt>/trunk</tt> directory in the 236251881Speter repository.</dd> 237251881Speter </dl> 238251881Speter </td> 239251881Speter</tr> 240251881Speter</table> 241251881Speter 242251881Speter<dl class="bookref"> 243251881Speter <dt>Book References:</dt> 244251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch05s04.html#svn-ch-5-sect-6.1">Choosing a repository layout</a></dd> 245251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re12.html">svn import</a></dd> 246251881Speter</dl> 247251881Speter</div> 248251881Speter 249251881Speter<!-- ==================================================================== --> 250251881Speter<div class="h2"> 251251881Speter<h2 id="installing">Installing a server</h2> 252251881Speter 253251881Speter<p>Make the repository available to clients via a network.</p> 254251881Speter 255251881Speter<table class="sidebyside"> 256251881Speter<tr> 257251881Speter <th>CVS</th> 258251881Speter <th>Subversion</th> 259251881Speter</tr> 260251881Speter<tr> 261251881Speter <td> 262251881Speter <dl> 263251881Speter <dt>Commands:</dt> 264251881Speter <dd>(too complex to demonstrate here)</dd> 265251881Speter 266251881Speter <dt>Explanation:</dt> 267251881Speter <dd>Export the repository via the cvs <em>pserver</em> program. 268251881Speter It can be launched by either <strong>inetd</strong> or a 269251881Speter client's <strong>ssh</strong> remote request.</dd> 270251881Speter 271251881Speter </dl> 272251881Speter </td> 273251881Speter <td> 274251881Speter <dl> 275251881Speter <dt>Commands:</dt> 276251881Speter <dd>(too complex to demonstrate here)</dd> 277251881Speter 278251881Speter <dt>Explanation:</dt> 279251881Speter <dd>Export the repository with the <em>Apache 2.0.x</em> server, 280251881Speter or via the <em>svnserve</em> program. The latter can run as a 281251881Speter standalone daemon, can be launched by <strong>inetd</strong>, or 282251881Speter invoked by a client's <strong>ssh</strong> remote request.</dd> 283251881Speter 284251881Speter </dl> 285251881Speter </td> 286251881Speter</tr> 287251881Speter</table> 288251881Speter 289251881Speter<dl class="bookref"> 290251881Speter <dt>Book References:</dt> 291251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch06.html">Server configuration</a></dd> 292251881Speter</dl> 293251881Speter 294251881Speter</div> 295251881Speter 296251881Speter<!-- ==================================================================== --> 297251881Speter<div class="h2"> 298251881Speter<h2 id="authenticating">Authenticating to a server</h2> 299251881Speter 300251881Speter<p>Have a network client prove its identity to a version 301251881Speter control server.</p> 302251881Speter 303251881Speter<table class="sidebyside"> 304251881Speter<tr> 305251881Speter <th>CVS</th> 306251881Speter <th>Subversion</th> 307251881Speter</tr> 308251881Speter<tr> 309251881Speter <td> 310251881Speter <dl> 311251881Speter <dt>Commands:</dt> 312251881Speter <dd><tt>$ cvs -d :pserver:user@host:/repos <em>command</em>…</tt></dd> 313251881Speter 314251881Speter <dt>Explanation:</dt> 315251881Speter 316251881Speter <dd>When contacting a repository, the client pre-emptively 317251881Speter "pushes" its authentication credentials at the server.</dd> 318251881Speter 319251881Speter </dl> 320251881Speter </td> 321251881Speter <td> 322251881Speter <dl> 323251881Speter <dt>Commands:</dt> 324251881Speter <dd><tt>$ svn <em>command</em> <em>URL</em>…</tt></dd> 325251881Speter <dd><tt>Password for 'user': XXXXXXX</tt></dd> 326251881Speter 327251881Speter <dt>Explanation:</dt> 328251881Speter 329251881Speter <dd>The client's authentication credentials are "pulled" from 330251881Speter the user interactively, and only when the server deems that a 331251881Speter challenge needs to be made. (And contrary to popular belief, 332251881Speter the <tt>--username</tt> and <tt>--password</tt> options are 333251881Speter merely values to be used <em>if</em> the server issues a 334251881Speter challenge; they do not "push" the credentials at the 335251881Speter server.)</dd> 336251881Speter 337251881Speter </dl> 338251881Speter </td> 339251881Speter</tr> 340251881Speter</table> 341251881Speter 342251881Speter<dl class="bookref"> 343251881Speter <dt>Book References:</dt> 344251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch06s02.html">Network Model</a></dd> 345251881Speter</dl> 346251881Speter 347251881Speter</div> 348251881Speter 349251881Speter<!-- ==================================================================== --> 350251881Speter<div class="h2"> 351251881Speter<h2 id="browsing">Browsing a repository</h2> 352251881Speter 353251881Speter<p>Browse the repository as a filesystem, perusing file 354251881Speter contents and history as well (older versions of files or 355251881Speter trees.)</p> 356251881Speter 357251881Speter<table class="sidebyside"> 358251881Speter<tr> 359251881Speter <th>CVS</th> 360251881Speter <th>Subversion</th> 361251881Speter</tr> 362251881Speter<tr> 363251881Speter <td> 364251881Speter <dl> 365251881Speter <dt>Commands:</dt> 366251881Speter <dd>(not possible with commandline client)</dd> 367251881Speter 368251881Speter <dt>Explanation:</dt> 369251881Speter 370251881Speter <dd>Not possible with commandline client. A third-party web 371251881Speter server tool such as ViewCVS must be used.</dd> 372251881Speter 373251881Speter </dl> 374251881Speter </td> 375251881Speter <td> 376251881Speter <dl> 377251881Speter <dt>Commands:</dt> 378251881Speter <dd><tt>$ svn list <em>URL</em> [-r <em>rev</em>] [-v]</tt></dd> 379251881Speter <dd><tt>$ svn cat <em>URL</em> [-r <em>rev</em>]</tt></dd> 380251881Speter 381251881Speter <dt>Explanation:</dt> 382251881Speter 383251881Speter <dd>The <tt>svn list</tt> and <tt>svn cat</tt> commands allow 384251881Speter interactive browsing of a repository (and all previous states of 385251881Speter a repository) from the commandline. (The <tt>--verbose [-v]</tt> 386251881Speter switch displays full listing information.) If Apache is being 387251881Speter used as a Subversion server process (i.e. clients access via 388251881Speter <strong>http://</strong>), then the latest version of the 389251881Speter repository can be directly browsed by entering <em>URL</em> into 390251881Speter any web browser. Additionally, a third-party web server tool 391251881Speter (such as ViewCVS) can be used with Subversion.</dd> 392251881Speter 393251881Speter </dl> 394251881Speter </td> 395251881Speter</tr> 396251881Speter</table> 397251881Speter 398251881Speter<dl class="bookref"> 399251881Speter <dt>Book References:</dt> 400251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re14.html">svn list</a></dd> 401251881Speter</dl> 402251881Speter 403251881Speter</div> 404251881Speter 405251881Speter<!-- ==================================================================== --> 406251881Speter<div class="h2"> 407251881Speter<h2 id="checkingout">Checking out a working copy</h2> 408251881Speter 409251881Speter<p>Create a workspace on local disk which mirrors a directory 410251881Speter in the repository.</p> 411251881Speter 412251881Speter<table class="sidebyside"> 413251881Speter<tr> 414251881Speter <th>CVS</th> 415251881Speter <th>Subversion</th> 416251881Speter</tr> 417251881Speter<tr> 418251881Speter <td> 419251881Speter <dl> 420251881Speter <dt>Commands:</dt> 421251881Speter <dd><tt>$ cvs -d /usr/local/repos checkout myproj</tt></dd> 422251881Speter <dd><tt>U myproj/foo.c</tt></dd> 423251881Speter <dd><tt>U myproj/bar.c</tt></dd> 424251881Speter <dd><tt>…</tt></dd> 425251881Speter 426251881Speter <dt>Explanation:</dt> 427251881Speter 428251881Speter <dd>Creates a local directory <tt>myproj</tt> which is a mirror 429251881Speter of the repository directory <tt>/myproj</tt>.</dd> 430251881Speter 431251881Speter </dl> 432251881Speter </td> 433251881Speter <td> 434251881Speter <dl> 435251881Speter <dt>Commands:</dt> 436251881Speter <dd><tt>$ svn checkout file:///usr/local/repos/trunk myproj</tt></dd> 437251881Speter <dd><tt>A myproj/foo.c</tt></dd> 438251881Speter <dd><tt>A myproj/bar.c</tt></dd> 439251881Speter <dd><tt>…</tt></dd> 440251881Speter 441251881Speter <dt>Explanation:</dt> 442251881Speter 443251881Speter <dd>Assuming that the original project data was imported into 444251881Speter the repository <tt>/trunk</tt> directory, this creates a local 445251881Speter directory <tt>myproj</tt> which is a mirror of the repository 446251881Speter directory <tt>/trunk</tt>. Standard Subversion convention is to 447251881Speter do "mainline" development in <tt>/trunk</tt>. See branching and 448251881Speter tagging sections for more details.</dd> 449251881Speter 450251881Speter </dl> 451251881Speter </td> 452251881Speter</tr> 453251881Speter</table> 454251881Speter 455251881Speter<dl class="bookref"> 456251881Speter <dt>Book References:</dt> 457251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch03s04.html">Initial Checkout</a></dd> 458251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re04.html">svn checkout</a></dd> 459251881Speter</dl> 460251881Speter 461251881Speter</div> 462251881Speter 463251881Speter<!-- ==================================================================== --> 464251881Speter<div class="h2"> 465251881Speter<h2 id="changeditems">Seeing locally changed items</h2> 466251881Speter 467251881Speter<p>Discover which items in the working copy have local 468251881Speter modifications or are scheduled for addition/deletion.</p> 469251881Speter 470251881Speter<table class="sidebyside"> 471251881Speter<tr> 472251881Speter <th>CVS</th> 473251881Speter <th>Subversion</th> 474251881Speter</tr> 475251881Speter<tr> 476251881Speter <td> 477251881Speter <dl> 478251881Speter <dt>Commands:</dt> 479251881Speter <dd><tt>$ cvs status</tt></dd> 480251881Speter <dd><tt>…</tt></dd> 481251881Speter <dd><tt>File: baz.c Status: Up-to-date</tt></dd> 482251881Speter <dd><tt>…</tt></dd> 483251881Speter <dd><tt>$ cvs update</tt></dd> 484251881Speter <dd><tt>M foo.c</tt></dd> 485251881Speter <dd><tt>U bar.c</tt></dd> 486251881Speter <dd><tt>…</tt></dd> 487251881Speter 488251881Speter <dt>Explanation:</dt> 489251881Speter 490251881Speter <dd>The <tt>cvs status</tt> command shows whether a file is 491251881Speter locally modified or out of date, including information about 492251881Speter working revision and branch info. Unfortunately, because the 493251881Speter output is so verbose and hard to read, many users run <tt>cvs 494251881Speter update</tt> instead, which shows a more compact listing of 495251881Speter modified files (and of course, it also causes the server to 496251881Speter merge changes into your working copy.)</dd> 497251881Speter 498251881Speter </dl> 499251881Speter </td> 500251881Speter <td> 501251881Speter <dl> 502251881Speter <dt>Commands:</dt> 503251881Speter <dd><tt>$ svn status</tt></dd> 504251881Speter <dd><tt>M foo.c</tt></dd> 505251881Speter <dd><tt>…</tt></dd> 506251881Speter 507251881Speter <dt>Explanation:</dt> 508251881Speter 509251881Speter <dd>Shows modified files only. Very fast, as it does not use 510251881Speter the network. Does not update your working copy, yet still shows 511251881Speter a single-line display, much like <tt>svn update</tt>. To see 512251881Speter working revision and branch information, run <tt>svn info</tt>.</dd> 513251881Speter 514251881Speter </dl> 515251881Speter </td> 516251881Speter</tr> 517251881Speter</table> 518251881Speter 519251881Speter<dl class="bookref"> 520251881Speter <dt>Book References:</dt> 521251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch03s05.html#svn-ch-3-sect-4.3.1">Examine Your Changes</a></dd> 522251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re26.html">svn status</a></dd> 523251881Speter</dl> 524251881Speter 525251881Speter</div> 526251881Speter 527251881Speter<!-- ==================================================================== --> 528251881Speter<div class="h2"> 529251881Speter<h2 id="outofdate">Seeing out-of-date items</h2> 530251881Speter 531251881Speter<p>Discover which items in the working copy are out-of-date 532251881Speter (i.e. newer versions exist in the repository.)</p> 533251881Speter 534251881Speter<table class="sidebyside"> 535251881Speter<tr> 536251881Speter <th>CVS</th> 537251881Speter <th>Subversion</th> 538251881Speter</tr> 539251881Speter<tr> 540251881Speter <td> 541251881Speter <dl> 542251881Speter <dt>Commands:</dt> 543251881Speter <dd><tt>$ cvs status</tt></dd> 544251881Speter <dd><tt>…</tt></dd> 545251881Speter <dd><tt>File: baz.c Status: Needs Patch</tt></dd> 546251881Speter <dd><tt>…</tt></dd> 547251881Speter <dd><tt>$ cvs -n update</tt></dd> 548251881Speter <dd><tt>M foo.c</tt></dd> 549251881Speter <dd><tt>U bar.c</tt></dd> 550251881Speter <dd><tt>…</tt></dd> 551251881Speter 552251881Speter <dt>Explanation:</dt> 553251881Speter 554251881Speter <dd>The <tt>cvs status</tt> command shows whether a file is 555251881Speter locally modified or out of date, including information about 556251881Speter working revision and branch info. A less verbose option is to 557251881Speter run <tt>cvs -n update</tt> instead, which shows a compact 558251881Speter listing of both out-of-date and locally modified files, without 559251881Speter actually updating the working copy.</dd> 560251881Speter 561251881Speter </dl> 562251881Speter </td> 563251881Speter <td> 564251881Speter <dl> 565251881Speter <dt>Commands:</dt> 566251881Speter <dd><tt>$ svn status -u</tt></dd> 567251881Speter <dd><tt>M 46 foo.c</tt></dd> 568251881Speter <dd><tt>M * 46 bar.c</tt></dd> 569251881Speter <dd><tt> * 46 baz.c</tt></dd> 570251881Speter <dd><tt>…</tt></dd> 571251881Speter 572251881Speter <dt>Explanation:</dt> 573251881Speter 574251881Speter <dd>Shows modified files (<tt>M</tt>) as well as out-of-date 575251881Speter files (<tt>*</tt>). Contacts repository, but doesn't modify the 576251881Speter working copy. To see working revision and branch information, 577251881Speter run <tt>svn info</tt>.</dd> 578251881Speter 579251881Speter </dl> 580251881Speter </td> 581251881Speter</tr> 582251881Speter</table> 583251881Speter 584251881Speter<dl class="bookref"> 585251881Speter <dt>Book References:</dt> 586251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch03s05.html#svn-ch-3-sect-4.3.1">Examine Your Changes</a></dd> 587251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re26.html">svn status</a></dd> 588251881Speter</dl> 589251881Speter 590251881Speter</div> 591251881Speter 592251881Speter<!-- ==================================================================== --> 593251881Speter<div class="h2"> 594251881Speter<h2 id="scheduling">Scheduling additions or deletions</h2> 595251881Speter 596251881Speter<p>Schedule a working-copy file or directory to be added or 597251881Speter removed from the repository.</p> 598251881Speter 599251881Speter<table class="sidebyside"> 600251881Speter<tr> 601251881Speter <th>CVS</th> 602251881Speter <th>Subversion</th> 603251881Speter</tr> 604251881Speter<tr> 605251881Speter <td> 606251881Speter <dl> 607251881Speter <dt>Commands:</dt> 608251881Speter <dd><tt>$ touch foo.c</tt></dd> 609251881Speter <dd><tt>$ cvs add foo.c</tt></dd> 610251881Speter <dd><tt>cvs server: scheduling file `blah' for addition</tt></dd> 611251881Speter <dd><tt>cvs server: use 'cvs commit' to add this file permanently</tt></dd> 612251881Speter <dd><tt> </tt></dd> 613251881Speter <dd><tt>$ mkdir new-dir</tt></dd> 614251881Speter <dd><tt>$ cvs add new-dir</tt></dd> 615251881Speter <dd><tt>Directory new-dir added to the repository</tt></dd> 616251881Speter <dd><tt> </tt></dd> 617251881Speter <dd><tt>$ rm bar.c</tt></dd> 618251881Speter <dd><tt>$ cvs rm bar.c</tt></dd> 619251881Speter <dd><tt>cvs remove: scheduling `bar.c' for removal</tt></dd> 620251881Speter <dd><tt>cvs remove: use 'cvs commit' to remove this file permanently</tt></dd> 621251881Speter <dd><tt> </tt></dd> 622251881Speter <dd><tt>$ rm -rf old-dir/*</tt></dd> 623251881Speter <dd><tt>$ cvs rm old-dir</tt></dd> 624251881Speter <dd><tt>cvs remove: Removing 3bits</tt></dd> 625251881Speter <dd><tt>…</tt></dd> 626251881Speter 627251881Speter 628251881Speter <dt>Explanation:</dt> 629251881Speter 630251881Speter <dd>Schedules a file or directory for addition or removal 631251881Speter to/from the repository. The repository will not be changed 632251881Speter until the user runs <tt>cvs commit</tt>, except for the case of 633251881Speter adding a directory, which immediately changes the repository. 634251881Speter Also, directories cannot be truly removed from the repository, 635251881Speter just emptied out. (<tt>cvs update -P</tt> will prune empty 636251881Speter directories from your working copy.)</dd> 637251881Speter 638251881Speter </dl> 639251881Speter </td> 640251881Speter <td> 641251881Speter <dl> 642251881Speter <dt>Commands:</dt> 643251881Speter <dd><tt>$ touch foo.c</tt></dd> 644251881Speter <dd><tt>$ svn add foo.c</tt></dd> 645251881Speter <dd><tt>A foo.c</tt></dd> 646251881Speter <dd><tt> </tt></dd> 647251881Speter <dd><tt>$ mkdir new-dir</tt></dd> 648251881Speter <dd><tt>$ svn add new-dir</tt></dd> 649251881Speter <dd><tt>A new-dir</tt></dd> 650251881Speter <dd><tt> </tt></dd> 651251881Speter <dd><tt>$ svn rm bar.c</tt></dd> 652251881Speter <dd><tt>D bar.c</tt></dd> 653251881Speter <dd><tt> </tt></dd> 654251881Speter <dd><tt>$ svn rm old-dir</tt></dd> 655251881Speter <dd><tt>D old-dir/file1</tt></dd> 656251881Speter <dd><tt>D old-dir/file2</tt></dd> 657251881Speter <dd><tt>…</tt></dd> 658251881Speter 659251881Speter <dt>Explanation:</dt> 660251881Speter 661251881Speter <dd>Schedules a file or directory for addition or removal 662251881Speter to/from the repository. The repository will not be changed 663251881Speter until the user runs <tt>svn commit</tt>. The scheduled 664251881Speter operations are shown as <tt>A</tt> or <tt>D</tt> by <tt>svn 665251881Speter status</tt>, and <tt>svn revert</tt> can un-do the scheduling. 666251881Speter Directories really can be deleted (though as with all deleted 667251881Speter items, continues to exist in history.)</dd> 668251881Speter 669251881Speter </dl> 670251881Speter </td> 671251881Speter</tr> 672251881Speter</table> 673251881Speter 674251881Speter<dl class="bookref"> 675251881Speter <dt>Book References:</dt> 676251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch03s05.html#svn-ch-3-sect-4.2">Make Changes to Your Working Copy</a></dd> 677251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re01.html">svn add</a></dd> 678251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re08.html">svn delete</a></dd> 679251881Speter</dl> 680251881Speter 681251881Speter</div> 682251881Speter 683251881Speter<!-- ==================================================================== --> 684251881Speter<div class="h2"> 685251881Speter<h2 id="copying">Copying and moving</h2> 686251881Speter 687251881Speter<p>Copy or move/rename a file or directory.</p> 688251881Speter 689251881Speter<table class="sidebyside"> 690251881Speter<tr> 691251881Speter <th>CVS</th> 692251881Speter <th>Subversion</th> 693251881Speter</tr> 694251881Speter<tr> 695251881Speter <td> 696251881Speter <dl> 697251881Speter <dt>Commands:</dt> 698251881Speter <dd>(not possible.)</dd> 699251881Speter 700251881Speter 701251881Speter <dt>Explanation:</dt> 702251881Speter 703251881Speter <dd>Not possible, unless an administrator directly mucks with 704251881Speter RCS files in the repository. (And in that case, no history 705251881Speter records the act of copying or renaming.)</dd> 706251881Speter 707251881Speter </dl> 708251881Speter </td> 709251881Speter <td> 710251881Speter <dl> 711251881Speter <dt>Commands:</dt> 712251881Speter <dd><tt>$ svn copy foo.c foo2.c</tt></dd> 713251881Speter <dd><tt>A foo2.c</tt></dd> 714251881Speter <dd><tt> </tt></dd> 715251881Speter <dd><tt>$ svn copy dir dir2</tt></dd> 716251881Speter <dd><tt>A dir2</tt></dd> 717251881Speter <dd><tt> </tt></dd> 718251881Speter <dd><tt>$ svn move bar.c baz.c</tt></dd> 719251881Speter <dd><tt>A baz.c</tt></dd> 720251881Speter <dd><tt>D bar.c</tt></dd> 721251881Speter <dd><tt> </tt></dd> 722251881Speter <dd><tt>$ svn move dirA dirB</tt></dd> 723251881Speter <dd><tt>A dirB</tt></dd> 724251881Speter <dd><tt>D dirA/file1</tt></dd> 725251881Speter <dd><tt>D dirA/file2</tt></dd> 726251881Speter <dd><tt>…</tt></dd> 727251881Speter 728251881Speter <dt>Explanation:</dt> 729251881Speter 730251881Speter <dd>The <tt>svn copy</tt> command schedules a file or directory 731251881Speter for addition to the repository, recording the "source" of the 732251881Speter copy. After committing, <tt>svn log</tt> on the copied item 733251881Speter will trace history back through the original copy-source. The 734251881Speter <tt>svn move</tt> command is exactly equivalent to running 735251881Speter <tt>svn copy</tt>, followed by an <tt>svn delete</tt> on the 736251881Speter copy-source: the result is a new item scheduled for addition 737251881Speter (with copy-history attached) and the original item scheduled for 738251881Speter deletion.</dd> 739251881Speter 740251881Speter </dl> 741251881Speter </td> 742251881Speter</tr> 743251881Speter</table> 744251881Speter 745251881Speter<dl class="bookref"> 746251881Speter <dt>Book References:</dt> 747251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/ch03s05.html#svn-ch-3-sect-4.2">Make Changes to Your Working Copy</a></dd> 748251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re07.html">svn copy</a></dd> 749251881Speter <dd><a href="http://svnbook.red-bean.com/svnbook/re18.html">svn move</a></dd> 750251881Speter</dl> 751251881Speter 752251881Speter 753251881Speter</div> 754251881Speter 755251881Speter<!-- ==================================================================== --> 756251881Speter<div class="h2"> 757251881Speter<h2>Finding the beginning of a branch</h2> 758251881Speter 759251881Speter<p>If you're attempting to merge an entire branch into another, you 760251881Speterneed to compare the "root" and "tip" of the source branch, and then 761251881Spetermerge those differences into a working copy of the target branch. 762251881SpeterObviously the "tip" of the branch can be represented by using the 763251881Speter<tt>HEAD</tt> keyword. But how do you find the "birth" revision of 764251881Speterthe source branch?</p> 765251881Speter 766251881Speter<p>The easiest solution is to run</p> 767251881Speter 768251881Speter<pre> 769251881Speter $ svn log -v --stop-on-copy source-branch-URL 770251881Speter … 771251881Speter</pre> 772251881Speter 773251881Speter<p>This command will display every change ever made to the branch, but 774251881Speter<tt>--stop-on-copy</tt> option will cause the output to stop as soon 775251881Speteras detects a copy operation in the branch's history. By definition, 776251881Speterthen, the very last log entry printed will show the copy being made. 777251881SpeterIt will look something like:</p> 778251881Speter 779251881Speter<pre> 780251881Speterr9189 | joe | 2004-03-22 10:10:47 -0600 (Mon, 22 Mar 2004) | 1 line 781251881SpeterChanged paths: 782251881Speter A /branches/mybranch (from /trunk:9188) 783251881Speter</pre> 784251881Speter 785251881Speter<p>In this case, you would then know to compare revisions 9189 and 786251881SpeterHEAD of the branch in order to perform the merge:</p> 787251881Speter 788251881Speter<pre> 789251881Speter $ svn merge -r9189:HEAD source-branch-URL target-branch-WC 790251881Speter … 791251881Speter</pre> 792251881Speter 793251881Speter</div> 794251881Speter 795251881Speter<!-- ==================================================================== --> 796251881Speter<div class="h2"> 797251881Speter<h2>Seeing all of a project's tags</h2> 798251881Speter 799251881Speter<p>Assuming you've been following a consistent policy for creating 800251881Spetertag-copies, then this is just a matter of running <tt>svn ls</tt> on a 801251881Speterdirectory containing your tags. Typically you would run it on the 802251881Speter<tt>/tags</tt> directory in your repository, although you're certainly 803251881Speterfree to organize this directory in a more complex way, or invent a 804251881Speterdifferent convention altogether.</p> 805251881Speter 806251881Speter<p>As an example, you can see all of Subversion's tags by running:</p> 807251881Speter 808251881Speter<pre> 809251881Speter $ svn ls --verbose http://svn.apache.org/repos/asf/subversion/tags 810251881Speter … 811251881Speter 7739 kfogel Nov 13 22:05 0.33.0/ 812251881Speter 7796 josander Nov 18 12:15 0.33.1/ 813251881Speter 7932 josander Dec 03 17:54 0.34.0/ 814251881Speter 8045 josander Dec 19 15:13 0.35.0/ 815251881Speter 8063 josander Dec 20 11:20 0.35.1/ 816251881Speter 8282 josander Jan 13 14:15 0.36.0/ 817251881Speter 8512 josander Jan 24 17:31 0.37.0/ 818251881Speter 8810 kfogel Feb 23 03:44 1.0.0/ 819251881Speter … 820251881Speter</pre> 821251881Speter 822251881Speter</div> 823251881Speter 824251881Speter<!-- ==================================================================== --> 825251881Speter<div class="h2"> 826251881Speter<h2>Seeing the differences between two tags</h2> 827251881Speter 828251881Speter<p>Just use <tt>svn diff</tt> in its fully expanded form, which 829251881Spetercompares any two URLs:</p> 830251881Speter 831251881Speter<pre> 832251881Speter $ svn diff tagURL1 tagURL2 833251881Speter … 834251881Speter</pre> 835251881Speter 836251881Speter</div> 837251881Speter 838251881Speter<!-- ==================================================================== --> 839251881Speter<div class="h2"> 840251881Speter<h2>Seeing logs between two tags</h2> 841251881Speter 842251881Speter<p>This is a somewhat common practice in CVS, and is doable in Subversion, 843251881Speterbut requires a little bit more work. Assuming that you've made two 844251881Spetertags of <tt>/trunk</tt> at different points in time, the ultimate goal 845251881Speterhere is to run </p> 846251881Speter 847251881Speter<pre> 848251881Speter $ svn log -rX:Y trunkURL 849251881Speter</pre> 850251881Speter 851251881Speter<p>…where X and Y are the revisions from which the two tags were 852251881Spetercopied. To discover X and Y, you can use the same technique 853251881Speterdescribed in the previous section ("finding the beginning of a 854251881Speterbranch".) Just use the <tt>--stop-on-copy</tt> option when logging the 855251881Speterhistory of each tag. No commits happen on tag directories, so the 856251881Speterfollowing commands should each produce exactly <em>one</em> log 857251881Speterentry:</p> 858251881Speter 859251881Speter<pre> 860251881Speter $ svn log -v --stop-on-copy tag1-URL 861251881Speter 862251881Speter r3520 | joe | 2004-03-12 15:28:43 -0600 (Fri, 12 Mar 2004) | 1 line 863251881Speter … 864251881Speter 865251881Speter $ svn log -v --stop-on-copy tag2-URL 866251881Speter a 867251881Speter r4177 | joe | 2004-03-12 15:28:43 -0600 (Fri, 12 Mar 2004) | 1 line 868251881Speter … 869251881Speter</pre> 870251881Speter 871251881Speter<p>So in this example, the values of X and Y are 3520 and 4177. Now 872251881Speteryou can view all <tt>/trunk</tt> changes between those two points in time:</p> 873251881Speter 874251881Speter<pre> 875251881Speter $ svn log -r3520:4177 trunkURL 876251881Speter … 877251881Speter</pre> 878251881Speter 879251881Speter</div> 880251881Speter 881251881Speter<!-- ==================================================================== --> 882251881Speter<div class="h2"> 883251881Speter<h2>Fixing an incorrect tag</h2> 884251881Speter 885251881Speter<p>If your tag is a bit off, you can "adjust" it just as people often 886251881Speterdo in CVS. Simply check out a working copy of the tag directory, make 887251881Speterany changes you wish, and commit.</p> 888251881Speter 889251881Speter<p>Remember, because branches and tags are directories, they can also 890251881Speterbe deleted when they're no longer of any use to your project. They'll 891251881Spetercontinue to exist in the repository's history.</p> 892251881Speter 893251881Speter 894251881Speter</div> 895251881Speter 896251881Speter<!-- ==================================================================== --> 897251881Speter<div class="h2"> 898251881Speter<h2>Creating/using "modules"</h2> 899251881Speter 900251881Speter<p>Compare CVS Modules vs. svn:externals.</p> 901251881Speter 902251881Speter</div> 903251881Speter 904251881Speter<!-- ==================================================================== --> 905251881Speter</body> 906251881Speter</html> 907