My favorites | Sign in
Logo
          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
<chapter id="svn.tour">
<title>Basic Usage</title>

<para>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.</para>

<para>Note that this chapter is not meant to be an exhaustive list
of all of Subversion's commands&mdash;rather, it's a conversational
introduction to the most common Subversion tasks that 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"/>.</para>


<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.tour.help">
<title>Help!</title>

<para>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&mdash;at
any time, a quick <userinput>svn help
<replaceable>subcommand</replaceable></userinput> will describe
the syntax, options, and behavior of the subcommand.</para>

<screen>
$ svn help import
import: Commit an unversioned file or tree into the repository.
usage: import [PATH] URL

Recursively commit a copy of PATH to URL.
If PATH is omitted '.' is assumed.
Parent directories are created as necessary in the repository.
If PATH is a directory, the contents of the directory are added
directly under URL.
Unversionable items such as device files and pipes are ignored
if --force is specified.

Valid options:
-q [--quiet] : print nothing, or only summary information
-N [--non-recursive] : obsolete; try --depth=files or --depth=immediates
--depth ARG : limit operation by depth ARG ('empty', 'files',
'immediates', or 'infinity')
&hellip;
</screen>

<sidebar>
<title>Options and Switches and Flags, Oh My!</title>

<para>The Subversion command-line client has numerous command
modifiers (which we call options), but there are two
distinct kinds of options: short options
are a single hyphen followed by a single letter, and
long options consist of two hyphens
followed by a number of letters (e.g., <literal>-s</literal>
and <literal>--this-is-a-long-option</literal>,
respectively). Every option has a long format, but only
certain options have an additional short format (these are
typically options that are frequently used). To
maintain clarity, we <emphasis>usually</emphasis> use the
long form in code examples, but when describing options, if
there's a short form, we'll provide the long form (to
improve clarity) and the short form (to make it easier to
remember). You should use whichever one you're more
comfortable with, but don't try to use both.</para>

</sidebar>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.tour.importing">
<title>Getting Data into Your Repository</title>

<para>You can get new files into your Subversion
repository in two ways: <command>svn import</command> and <command>svn
add</command>. We'll discuss <command>svn import</command> now
and will discuss <command>svn add</command> later in this
chapter when we review a typical day with Subversion.</para>

<!-- =============================================================== -->
<sect2 id="svn.tour.importing.import">
<title>svn import</title>

<para>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. You typically
use this when you have an existing tree of files that you want to
begin tracking in your Subversion repository. For example:</para>

<screen>
$ svnadmin create /var/svn/newrepos
$ svn import mytree file:///var/svn/newrepos/some/project \
-m "Initial import"
Adding mytree/foo.c
Adding mytree/bar.c
Adding mytree/subdir
Adding mytree/subdir/quux.h

Committed revision 1.
</screen>

<para>The previous example copied the contents of directory
<filename>mytree</filename> under the directory
<filename>some/project</filename> in the repository:</para>

<screen>
$ svn list file:///var/svn/newrepos/some/project
bar.c
foo.c
subdir/
</screen>

<para>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.</para>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.importing.layout">
<title>Recommended Repository Layout</title>

<para>While Subversion's flexibility allows you to lay out 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:</para>

<screen>
$ svn list file:///var/svn/repos
/trunk
/branches
/tags
</screen>

<para>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 project roots.</para>

</sect2>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.tour.initial">
<title>Initial Checkout</title>

<para>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:</para>


<screen>
$ svn checkout http://svn.collab.net/repos/svn/trunk
A trunk/Makefile.in
A trunk/ac-helpers
A trunk/ac-helpers/install.sh
A trunk/ac-helpers/install-sh
A trunk/build.conf
&hellip;
Checked out revision 8810.
</screen>

<sidebar>
<title>What's in a Name?</title>

<para>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.</para>

<para>Subversion internally handles certain bits of
data&mdash;for example, property names, pathnames, and log
messages&mdash;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).</para>

<para>In WebDAV exchanges and older versions of some of
Subversion's administrative files, paths are used as XML
attribute values, and property names in XML tag names. This
means that pathnames can contain only legal XML (1.0)
characters, and properties are further limited to ASCII
characters. Subversion also prohibits <literal>TAB</literal>,
<literal>CR</literal>, and <literal>LF</literal> characters in
path names to prevent paths from being broken up in diffs or
in the output of commands such as <command>svn log</command>
or <command>svn status</command>.</para>

<para>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&mdash;to create
<quote>legally correct</quote> versions for internal
use it will automatically escape illegal
path characters as needed in URLs that you type.</para>

</sidebar>

<para>Although the preceding 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:</para>

<screen>
$ svn checkout \
http://svn.collab.net/repos/svn/trunk/subversion/tests/cmdline/
A cmdline/revert_tests.py
A cmdline/diff_tests.py
A cmdline/autoprop_tests.py
A cmdline/xmltests
A cmdline/xmltests/svn-test.sh
&hellip;
Checked out revision 8810.
</screen>

<para>Since Subversion uses a copy-modify-merge
model instead of lock-modify-unlock (see
<xref linkend="svn.basic.vsn-models"/>), you can immediately
make 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
it, move it around, even delete the entire working copy and
forget about it.</para>

<warning>
<para>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.</para>
</warning>

<para>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.</para>

<sidebar>
<title>What's with the .svn Directory?</title>

<para>Every directory in a working copy contains an
administrative area&mdash;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.</para>

<para>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 <userinput>svn
update</userinput> from a parent directory. The Subversion
client will download the directory you've deleted, with a
new <filename>.svn</filename> area as well.</para>
</sidebar>

<para>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:</para>

<screen>
$ svn checkout http://svn.collab.net/repos/svn/trunk subv
A subv/Makefile.in
A subv/ac-helpers
A subv/ac-helpers/install.sh
A subv/ac-helpers/install-sh
A subv/build.conf
&hellip;
Checked out revision 8810.
</screen>

<para>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.</para>


<sect2 id="svn.tour.initial.disabling-password-caching">
<title>Disabling Password Caching</title>

<para>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 reenter
your password for future operations. If you're concerned
about caching your Subversion passwords,
<footnote>
<para>Of course, you're not terribly worried&mdash;first
because you know that you can't
<emphasis>really</emphasis> delete anything from
Subversion, and second because your Subversion password
isn't the same as any of the other 3 million passwords
you have, right? Right?</para>
</footnote>
you can disable caching either permanently or on a
case-by-case basis.</para>

<para>To disable password caching for a particular one-time
command, pass the <option >--no-auth-cache</option > option on
the command line. 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.</para>

</sect2>

<sect2 id="svn.tour.initial.different-user">
<title>Authenticating As a Different User</title>

<para>Since Subversion caches auth credentials by default (both
username and password), it conveniently remembers who you were
acting as the last time you modified your working copy. But
sometimes that's not helpful&mdash;particularly if you're
working in a shared working copy such as a system
configuration directory or a web server document root. In this
case, just pass the <option>--username</option> option on the
command line, and Subversion will attempt to authenticate as
that user, prompting you for a password if necessary.</para>

</sect2>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.tour.cycle">
<title>Basic Work Cycle</title>

<para>Subversion has numerous features, options, bells, and
whistles, but on a day-to-day basis, odds are that you will use
only 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.</para>

<para>The typical work cycle looks like this:</para>

<orderedlist>
<listitem>
<para>Update your working copy.</para>
<itemizedlist>
<listitem>
<para><command>svn update</command></para>
</listitem>
</itemizedlist>

</listitem>

<listitem>
<para>Make changes.</para>
<itemizedlist>
<listitem>
<para><command>svn add</command></para>
</listitem>
<listitem>
<para><command>svn delete</command></para>
</listitem>
<listitem>
<para><command>svn copy</command></para>
</listitem>
<listitem>
<para><command>svn move</command></para>
</listitem>
</itemizedlist>
</listitem>

<listitem>
<para>Examine your changes.</para>
<itemizedlist>
<listitem>
<para><command>svn status</command></para>
</listitem>
<listitem>
<para><command>svn diff</command></para>
</listitem>
</itemizedlist>
</listitem>

<listitem>
<para>Possibly undo some changes.</para>
<itemizedlist>
<listitem>
<para><command>svn revert</command></para>
</listitem>
</itemizedlist>
</listitem>


<listitem>
<para>Resolve conflicts (merge others' changes).</para>
<itemizedlist>
<listitem>
<para><command>svn update</command></para>
</listitem>
<listitem>
<para><command>svn resolve</command></para>
</listitem>
</itemizedlist>
</listitem>

<listitem>
<para>Commit your changes.</para>
<itemizedlist>
<listitem>
<para><command>svn commit</command></para>
</listitem>
</itemizedlist>
</listitem>
</orderedlist>

<!-- =============================================================== -->
<sect2 id="svn.tour.cycle.update">
<title>Update Your Working Copy</title>

<para>When working on a project with a team, you'll want to
update your working copy to receive any changes other developers
on the project have made since your last update. Use
<command>svn update</command> to bring your working copy into
sync with the latest revision in the repository:</para>

<screen>
$ svn update
U foo.c
U bar.c
Updated to revision 2.
</screen>

<para>In this case, it appears that someone 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.</para>

<para>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, run <userinput>svn help update</userinput>.</para>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.cycle.edit">
<title>Make Changes to Your Working Copy</title>

<para>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, and so on. 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.</para>

<para>You can make two kinds of changes to your
working copy: <firstterm>file changes</firstterm>
and <firstterm>tree changes</firstterm>. 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, it handles binary files just as easily as it handles
text files&mdash;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.</para>

<sidebar>
<title>Versioning Symbolic Links</title>

<para>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 that 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.</para>

<para>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 that
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.</para> </sidebar>

<para>Here is an overview of the five Subversion subcommands
that you'll use most often to make tree changes:</para>

<variablelist>

<varlistentry>
<term><userinput>svn add foo</userinput></term>
<listitem>
<para>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 want only to add
<filename>foo</filename> itself, pass the
<option>--depth empty</option> option.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><userinput>svn delete foo</userinput></term>
<listitem>
<para>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.
<footnote>
<para>Of course, nothing is ever totally deleted from
the repository&mdash;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.basicmerging.resurrect"
/>.</para>
</footnote>
</para>
</listitem>
</varlistentry>

<varlistentry>
<term><userinput>svn copy foo bar</userinput></term>
<listitem>
<para>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 unless you pass the
<option>--parents</option> option.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><userinput>svn move foo bar</userinput></term>
<listitem>
<para>This command is exactly the same as running
<userinput>svn copy foo bar; svn delete foo</userinput>.
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 unless you pass the
<option>--parents</option> option.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><userinput>svn mkdir blort</userinput></term>
<listitem>
<para>This command is exactly the same as running
<userinput>mkdir blort; svn add blort</userinput>. That is,
a new directory named <filename>blort</filename> is
created and scheduled for addition.</para>
</listitem>
</varlistentry>

</variablelist>

<sidebar>
<title>Changing the Repository Without a Working Copy</title>

<para>There <emphasis>are</emphasis> some use cases that
immediately commit tree changes to the repository. This
happens only 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).</para>

<para>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 aforementioned actions represents an
immediate commit.</para>

</sidebar>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.cycle.examine">
<title>Examine Your Changes</title>

<para>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>.</para>

<sidebar>
<title>Look Ma! No Network!</title>

<para>You can use the commands <command>svn status</command>,
<command>svn diff</command>, and <command>svn
revert</command> 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 traveling on an airplane, riding a
commuter train, or hacking on the beach.
<footnote>
<para>And you don't have a WLAN card. Thought
you got us, huh?</para>
</footnote>
</para>

<para>Subversion does this by keeping private caches of
pristine versions of each versioned file inside the
<filename>.svn</filename> administrative areas. This allows
Subversion to report&mdash;and revert&mdash;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&mdash;even if you
have a fast Internet connection, it's much faster to send only a
file's changes rather than the whole file to the
server.</para>

</sidebar>

<para>Subversion has been optimized to help you with this task,
and it 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.</para>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.examine.status">
<title>See an overview of your changes</title>

<para>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.</para>

<sidebar>
<title>CVS Users: Hold That Update!</title>

<para>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&mdash;without accessing the repository
or potentially incorporating new changes published by
other users.</para>

<para>In Subversion, <command>svn update</command> does just
that&mdash;it updates your working copy with any changes
committed to the repository since the last time you
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.</para>

</sidebar>

<para>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. Here 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>.)</para>

<screen>
? scratch.c # file is not under version control
A stuff/loot/bloo.h # file is scheduled for addition
C stuff/loot/lump.c # file has textual conflicts from an update
D stuff/fish.c # file is scheduled for deletion
M bar.c # the content in bar.c has local modifications
</screen>

<para>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:</para>

<variablelist>

<varlistentry>
<term><computeroutput>A item</computeroutput></term>
<listitem>
<para>The file, directory, or symbolic link
<filename>item</filename> has been scheduled for
addition into the repository.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><computeroutput>C item</computeroutput></term>
<listitem>

<para>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 (and weren't
resolved during the update). You must resolve this
conflict before committing your changes to the
repository.</para>

</listitem>
</varlistentry>

<varlistentry>
<term><computeroutput>D item</computeroutput></term>
<listitem>
<para>The file, directory, or symbolic link
<filename>item</filename> has been scheduled for
deletion from the repository.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><computeroutput>M item</computeroutput></term>
<listitem>
<para>The contents of the file <filename>item</filename>
have been modified.</para>
</listitem>
</varlistentry>

</variablelist>

<para>If you pass a specific path to <command>svn
status</command>, you get information about that item
alone:</para>

<screen>
$ svn status stuff/fish.c
D stuff/fish.c
</screen>

<para><command>svn status</command> also has a
<option>--verbose</option> (<option>-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:</para>

<screen>
$ svn status -v
M 44 23 sally README
44 30 sally INSTALL
M 44 20 harry bar.c
44 18 ira stuff
44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
44 21 sally stuff/things
A 0 ? ? stuff/things/bloo.h
44 36 harry stuff/things/gloo.c
</screen>

<para>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.</para>

<para>None of the prior invocations to <command>svn
status</command> contact the repository&mdash;instead, they
compare the metadata in the <filename>.svn</filename>
directory with the working copy. Finally, there is the
<option>--show-updates</option> (<option>-u</option>)
option, which contacts the repository and adds information
about things that are out of date:</para>

<screen>
$ svn status -u -v
M * 44 23 sally README
M 44 20 harry bar.c
* 44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
A 0 ? ? stuff/things/bloo.h
Status against revision: 46
</screen>

<para>Notice the two asterisks: if you were to run
<userinput>svn update</userinput> at this point, you would
receive changes to <filename>README</filename>
and <filename>trout.c</filename>. This tells you some very
useful information&mdash;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).</para>

<para><command>svn status</command> can display much more
information about the files and directories in your
working copy than we've shown here&mdash;for an exhaustive
description of <command>svn status</command> and its
output, see <xref linkend="svn.ref.svn.c.status"/>.</para>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.examine.diff">
<title>Examine the details of your local modifications</title>

<para>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 <userinput>svn diff</userinput> with no arguments, which
prints out file changes in <firstterm>unified diff
format</firstterm>:</para>

<screen>
$ svn diff
Index: bar.c
===================================================================
--- bar.c (revision 3)
+++ bar.c (working copy)
@@ -1,7 +1,12 @@
+#include &lt;sys/types.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;unistd.h&gt;
+
+#include &lt;stdio.h&gt;

int main(void) {
- printf("Sixty-four slices of American Cheese...\n");
+ printf("Sixty-five slices of American Cheese...\n");
return 0;
}

Index: README
===================================================================
--- README (revision 3)
+++ README (working copy)
@@ -193,3 +193,4 @@
+Note to self: pick up laundry.

Index: stuff/fish.c
===================================================================
--- stuff/fish.c (revision 1)
+++ stuff/fish.c (working copy)
-Welcome to the file known as 'fish'.
-Information on fish will be here soon.

Index: stuff/things/bloo.h
===================================================================
--- stuff/things/bloo.h (revision 8)
+++ stuff/things/bloo.h (working copy)
+Here is a new file to describe
+things about bloo.
</screen>

<para>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.</para>

<para>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:</para>

<screen>
$ svn diff &gt; patchfile
</screen>

<para>You could, for example, email the patch file to another
developer for review or testing prior to a commit.</para>

<para>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</option>
(<option>-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
<userinput>svn diff --diff-cmd /usr/bin/diff --extensions '-i'
foo.c</userinput>.</para>

</sect3>

</sect2>


<!-- =============================================================== -->
<sect2 id="svn.tour.cycle.revert">
<title>Undoing Working Changes</title>


<para>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.</para>

<para>This is a perfect opportunity to use <command>svn
revert</command>:</para>

<screen>
$ svn revert README
Reverted 'README'
</screen>

<para>Subversion reverts the file to its premodified 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&mdash;for
example, you might decide that you don't want to add a new
file after all:</para>

<screen>
$ svn status foo
? foo

$ svn add foo
A foo

$ svn revert foo
Reverted 'foo'

$ svn status foo
? foo
</screen>

<note>
<para><userinput>svn revert <replaceable>item</replaceable></userinput> has exactly the same
effect as deleting <replaceable>item</replaceable> from
your working copy and then running <userinput>svn update -r
BASE <replaceable>item</replaceable></userinput>. However,
if you're reverting a file, <command>svn revert</command>
has one very noticeable difference&mdash;it doesn't have
to communicate with the repository to restore your
file.</para>
</note>

<para>Or perhaps you mistakenly removed a file from version
control:</para>

<screen>
$ svn status README

$ svn delete README
D README

$ svn revert README
Reverted 'README'

$ svn status README
</screen>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.cycle.resolve">
<title>Resolve Conflicts (Merging Others' Changes)</title>

<para>We've already seen how <userinput>svn status -u</userinput>
can predict conflicts. Suppose you run <userinput>svn
update</userinput> and some interesting things occur:</para>

<screen>
$ svn update
U INSTALL
G README
Conflict discovered in 'bar.c'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h) help for more options:
</screen>

<para>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.</para>

<para>But the next two lines are part of a feature (new in
Subversion 1.5) called <firstterm>interactive conflict
resolution</firstterm>. This means that the changes from the
server overlapped with your own, and you have the opportunity
to resolve this conflict. The most commonly used options are
displayed, but you can see all of the options by
typing <replaceable>h</replaceable>:</para>

<screen>
&hellip;
(p) postpone - mark the conflict to be resolved later
(df) diff-full - show all changes made to merged file
(e) edit - change merged file in an editor
(r) resolved - accept merged version of file
(mf) mine-full - accept my version of entire file (ignore their changes)
(tf) theirs-full - accept their version of entire file (lose my changes)
(l) launch - launch external tool to resolve conflict
(h) help - show this list
</screen>

<para>Let's briefly review each of these options before we go
into detail on what each option means.</para>

<variablelist>
<varlistentry>
<term>(<computeroutput>p</computeroutput>)ostpone</term>
<listitem>

<para>Leave the file in a conflicted state for you to
resolve after your update is complete.</para>

</listitem>
</varlistentry>



<varlistentry>
<term>(<computeroutput>d</computeroutput>)iff</term>
<listitem>

<para>Display the differences between the base revision
and the conflicted file itself in unified diff format.</para>

</listitem>
</varlistentry>


<varlistentry>
<term>(<computeroutput>e</computeroutput>)dit</term>
<listitem>

<para>Open the file in conflict with your favorite editor,
as set in the environment variable
<literal>EDITOR</literal>.</para>

</listitem>
</varlistentry>


<varlistentry>
<term>(<computeroutput>r</computeroutput>)esolved</term>
<listitem>

<para>After editing a file, tell
<command>svn</command> that you've resolved the
conflicts in the file and that it should accept the
current contents&mdash;basically that you've
<quote>resolved</quote> the conflict.</para>

</listitem>
</varlistentry>

<varlistentry>
<term>(<computeroutput>m</computeroutput>)ine-(<computeroutput>f</computeroutput>)ull</term>
<listitem>

<para>Discard the newly received changes from the server
and use only your local changes for the file under review.</para>

</listitem>
</varlistentry>

<varlistentry>
<term>(<computeroutput>t</computeroutput>)heirs-(<computeroutput>f</computeroutput>)ull</term>
<listitem>

<para>Discard your local changes to the file under review
and use only the newly received changes from the
server.</para>

</listitem>
</varlistentry>

<varlistentry>
<term>(<computeroutput>l</computeroutput>)aunch</term>
<listitem>

<para>Launch an external program to perform the conflict
resolution. This requires a bit of preparation
beforehand.</para>

</listitem>
</varlistentry>

<varlistentry>
<term>(<computeroutput>h</computeroutput>)elp</term>
<listitem>

<para>Show the list of all possible commands you can use
in interactive conflict resolution.</para>

</listitem>
</varlistentry>

</variablelist>

<para>We'll cover these commands in more detail now, grouping
them together by related functionality.</para>


<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.resolve.diff">

<title>Viewing conflict differences interactively</title>

<para>Before deciding how to attack a conflict interactively,
odds are that you'd like to see exactly what is in conflict,
and the <firstterm>diff</firstterm> command
(<userinput>d</userinput>) is what you'll use for this:</para>

<screen>
&hellip;
Select: (p) postpone, (df) diff-full, (e) edit,
(h)elp for more options : d
--- .svn/text-base/sandwich.txt.svn-base Tue Dec 11 21:33:57 2007
+++ .svn/tmp/tempfile.32.tmp Tue Dec 11 21:34:33 2007
@@ -1 +1,5 @@
-Just buy a sandwich.
+&lt;&lt;&lt;&lt;&lt;&lt;&lt; .mine
+Go pick up a cheesesteak.
+=======
+Bring me a taco!
+&gt;&gt;&gt;&gt;&gt;&gt;&gt; .r32
&hellip;
</screen>

<para>The first line of the diff content shows the previous
contents of the working copy (the <literal>BASE</literal>
revision), the next content line is your change, and the
last content line is the change that was just received from
the server (<emphasis>usually</emphasis> the
<literal>HEAD</literal> revision). With this information in
hand, you're ready to move on to the next action.</para>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.resolve.resolve">

<title>Resolving conflict differences interactively</title>

<para>There are four different ways to resolve conflicts
interactively&mdash;two of which allow you to selectively
merge and edit changes, and two of which allow you to simply
pick a version of the file and move along.</para>

<para>If you wish to choose some combination of your local
changes, you can use the <quote>edit</quote> command
(<userinput>e</userinput>) to manually edit the file with
conflict markers in a text editor (determined by the
<literal>EDITOR</literal> environment variable). Editing
the file by hand in your favorite text editor is a somewhat
low-tech way of remedying conflicts (see <xref
linkend="svn.tour.cycle.resolve.byhand"/> for a
walkthrough), so some people like to use fancy graphical
merge tools instead.</para>

<para>To use a merge tool, you need to either set the
<literal>SVN_MERGE</literal> environment variable or define
the <literal>merge-tool-cmd</literal> option in your
Subversion configuration file (see <xref
linkend="svn.advanced.confarea.opts"/> for more details).
Subversion will pass four arguments to the merge tool: the
<literal>BASE</literal> revision of the file, the revision
of the file received from the server as part of the update,
the copy of the file containing your local edits, and
the merged copy of the file (which contains conflict
markers). If your merge tool is expecting arguments in a
different order or format, you'll need to write a wrapper
script for Subversion to invoke. After you've edited the
file, if you're satisfied with the changes you've made, you
can tell Subversion that the edited file is no longer in
conflict by using the <quote>resolve</quote> command
(<literal>r</literal>).</para>

<!-- TODO(fitz): I think the above detail on the merge tool -->
<!-- should probably be in ch07 -->

<para>If you decide that you don't need to merge any changes,
but just want to accept one version of the file or the
other, you can either choose your changes (a.k.a.
<quote>mine</quote>) by using the <quote>mine-full</quote>
command (<userinput>mf</userinput>) or choose theirs by using the
<quote>theirs-full</quote> command
(<userinput>tf</userinput>).</para>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.resolve.pending">

<title>Postponing conflict resolution</title>

<para>This may sound like an appropriate section for avoiding
marital disagreements, but it's actually still about
Subversion, so read on. If you're doing an update and
encounter a conflict that you're not prepared to review or
resolve, you can type <userinput>p</userinput> to postpone
resolving a conflict on a file-by-file basis when you run
<userinput>svn update</userinput>. If you're running an update
and don't want to resolve any conflicts, you can pass the
<option>--non-interactive</option> option to <command>svn
update</command>, and any file in conflict will be marked
with a <computeroutput>C</computeroutput>
automatically.</para>

<para>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 after the
update has completed. When you postpone a conflict
resolution, <command>svn</command> typically does three
things to assist you in noticing and resolving that
conflict:</para>

<itemizedlist>

<listitem>
<para>Subversion prints a <computeroutput>C</computeroutput>
during the update and remembers that the file is in a
state of conflict.</para>
</listitem>

<listitem>
<para>If Subversion considers the file to be mergeable, it
places <firstterm>conflict
markers</firstterm>&mdash;special strings of text that
delimit the <quote>sides</quote> of the
conflict&mdash;into the file to visibly demonstrate the
overlapping areas. (Subversion uses the
<literal>svn:mime-type</literal> property to decide whether a
file is capable of contextual, line-based merging. See
<xref linkend="svn.advanced.props.special.mime-type"/>
to learn more.)</para>
</listitem>

<listitem>
<para>For every conflicted file, Subversion places three
extra unversioned files in your working copy:</para>

<variablelist>

<varlistentry>
<term><filename>filename.mine</filename></term>
<listitem>
<para>This is your file as it existed in your working
copy before you updated your working copy&mdash;that
is, without conflict markers. This file has only
your latest changes in it. (If Subversion considers
the file to be unmergeable, the
<filename>.mine</filename> file isn't created, since
it would be identical to the working file.)</para>
</listitem>
</varlistentry>

<varlistentry>
<term><filename>filename.r<replaceable>OLDREV</replaceable>
</filename></term>
<listitem>
<para>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.</para>
</listitem>
</varlistentry>

<varlistentry>
<term><filename>filename.r<replaceable>NEWREV</replaceable>
</filename></term>
<listitem>
<para>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.</para>
</listitem>
</varlistentry>

</variablelist>

<para>Here <replaceable>OLDREV</replaceable> is the revision number
of the file in your <filename>.svn</filename> directory,
and <replaceable>NEWREV</replaceable> is the revision number of
the repository <literal>HEAD</literal>.</para>
</listitem>

</itemizedlist>

<para>For example, Sally makes changes to the file
<filename>sandwich.txt</filename>, but does not yet commit
those changes. Meanwhile, Harry commits changes to that
same file. Sally updates her working copy before committing
and she gets a conflict, which she postpones:</para>

<screen>
$ svn update
Conflict discovered in 'sandwich.txt'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h)elp for more options : p
C sandwich.txt
Updated to revision 2.
$ ls -1
sandwich.txt
sandwich.txt.mine
sandwich.txt.r1
sandwich.txt.r2
</screen>

<para>At this point, Subversion will <emphasis>not</emphasis>
allow Sally to commit the file
<filename>sandwich.txt</filename> until the three temporary
files are removed:</para>

<screen>
$ svn commit -m "Add a few more things"
svn: Commit failed (details follow):
svn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict
</screen>

<para>If you've postponed a conflict, you need to resolve the
conflict before Subversion will allow you to commit your
changes. You'll do this with the <command>svn
resolve</command> command and one of several arguments to
the <option>--accept</option> option.</para>

<para>If you want to choose the version of the file that you
last checked out before making your edits, choose
the <replaceable>base</replaceable> argument.</para>

<para>If you want to choose the version that contains only
your edits, choose the <replaceable>mine-full</replaceable>
argument.</para>

<para>If you want to choose the version that your most recent
update pulled from the server (and thus discarding your
edits entirely), choose
the <replaceable>theirs-full</replaceable> argument.</para>

<para>However, if you want to pick and choose from your
changes and the changes that your update fetched from the
server, merge the conflicted text <quote>by hand</quote> (by
examining and editing the conflict markers within the file)
and then choose the <replaceable>working</replaceable>
argument.</para>

<para><command>svn resolve</command> removes the three
temporary files and accepts the version of the file that you
specified with the <option>--accept</option> option, and
Subversion no longer considers the file to be in a state of
conflict:</para>

<screen>
$ svn resolve --accept working sandwich.txt
Resolved conflicted state of 'sandwich.txt'
</screen>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.resolve.byhand">
<title>Merging conflicts by hand</title>

<para>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.</para>

<para>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 conflict.
First, let's take a look at the file:</para>

<screen>
$ cat sandwich.txt
Top piece of bread
Mayonnaise
Lettuce
Tomato
Provolone
&lt;&lt;&lt;&lt;&lt;&lt;&lt; .mine
Salami
Mortadella
Prosciutto
=======
Sauerkraut
Grilled Chicken
&gt;&gt;&gt;&gt;&gt;&gt;&gt; .r2
Creole Mustard
Bottom piece of bread
</screen>

<para>The strings of less-than signs, equals 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:</para>

<screen>
&lt;&lt;&lt;&lt;&lt;&lt;&lt; .mine
Salami
Mortadella
Prosciutto
=======
</screen>

<para>The text between the second and third sets of conflict
markers is the text from Sally's commit:</para>

<screen>
=======
Sauerkraut
Grilled Chicken
&gt;&gt;&gt;&gt;&gt;&gt;&gt; .r2
</screen>

<para>Usually you won't want to just delete the conflict
markers and Sally's changes&mdash;she's going to be awfully
surprised when the sandwich arrives and it's not what she
wanted. 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.
<footnote>
<para>And if you ask them for it, they may very well ride
you out of town on a rail.</para>
</footnote>
Once you've agreed on the changes you will commit, edit
your file and remove the conflict markers:</para>

<screen>
Top piece of bread
Mayonnaise
Lettuce
Tomato
Provolone
Salami
Mortadella
Prosciutto
Creole Mustard
Bottom piece of bread
</screen>

<para>Now use <command>svn resolve</command>, and you're
ready to commit your changes:</para>

<screen>
$ svn resolve --accept working sandwich.txt
Resolved conflicted state of 'sandwich.txt'
$ svn commit -m "Go ahead and use my sandwich, discarding Sally's edits."
</screen>

<para>Note that <command>svn resolve</command>, unlike most of
the other commands we deal with in this chapter, requires
that you explicitly list any filenames that you wish to
resolve. In any case, you want to be careful and use
<command>svn resolve</command> only when you're certain that
you've fixed the conflict in your file&mdash;once the
temporary files are removed, Subversion will let you commit
the file even if it still contains conflict markers.</para>

<para>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&mdash;including your
file as it was before you updated. You can even use a
third-party interactive merging tool to examine those three
files.</para>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.resolve.theirsfull">
<title>Discarding your changes in favor of a newly fetched revision</title>

<para>If you get a conflict and decide that you want to throw
out your changes, you can run <userinput>svn resolve --accept
theirs-full <replaceable>CONFLICTED-PATH</replaceable></userinput> and Subversion will discard your edits
and remove the temporary files:</para>

<screen>
$ svn update
Conflict discovered in 'sandwich.txt'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h) help for more options: p
C sandwich.txt
Updated to revision 2.
$ ls sandwich.*
sandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1
$ svn resolve --accept theirs-full sandwich.txt
Resolved conflicted state of 'sandwich.txt'
</screen>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.cycle.resolve.revert">
<title>Punting: Using svn revert</title>

<para>If you decide that you want to throw out your changes
and start your edits again (whether this occurs after a
conflict or anytime), just revert your changes:</para>

<screen>
$ svn revert sandwich.txt
Reverted 'sandwich.txt'
$ ls sandwich.*
sandwich.txt
</screen>

<para>Note that when you revert a conflicted file, you don't
have to use <command>svn resolve</command>.</para>

</sect3>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.cycle.commit">
<title>Commit Your Changes</title>

<para>Finally! Your edits are finished, you've merged all
changes from the server, and you're ready to commit your
changes to the repository.</para>

<para>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:</para>

<screen>
$ svn commit -m "Corrected number of cheese slices."
Sending sandwich.txt
Transmitting file data .
Committed revision 3.
</screen>

<para>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</option> (<option>-F</option>) option:</para>

<screen>
$ svn commit -F logmsg
Sending sandwich.txt
Transmitting file data .
Committed revision 4.
</screen>

<para>If you fail to specify either the
<option>--message</option> or <option>--file</option> option,
Subversion will automatically launch your favorite editor
(see the information on <literal>editor-cmd</literal> in
<xref linkend="svn.advanced.confarea.opts.config"/>) for composing a log
message.</para>

<tip>
<para>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, and then abort:</para>

<screen>
$ svn commit
Waiting for Emacs...Done

Log message unchanged or not specified
(a)bort, (c)ontinue, (e)dit
a
$
</screen>
</tip>

<para>The repository doesn't know or care whether your changes make
any sense as a whole; it checks only to make sure 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 are out of date:</para>

<screen>
$ svn commit -m "Add another rule"
Sending rules.txt
svn: Commit failed (details follow):
svn: File '/sandwich.txt' is out of date
&hellip;
</screen>

<para>(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.)</para>

<para>At this point, you need to run <userinput>svn
update</userinput>, deal with any merges or conflicts that
result, and attempt your commit again.</para>

<para>That covers the basic work cycle for using Subversion.
Subversion offers many other features 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.</para>

</sect2>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.tour.history">
<title>Examining History</title>

<para>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> it.</para>

<para>Several commands can provide you with
historical data from the repository:</para>

<variablelist>

<varlistentry>
<term><command>svn log</command></term>
<listitem>
<para>Shows you broad information: log messages with date
and author information attached to revisions and which
paths changed in each revision</para>
</listitem>
</varlistentry>

<varlistentry>
<term><command>svn diff</command></term>
<listitem>
<para>Shows line-level details of a particular change</para>
</listitem>
</varlistentry>

<varlistentry>
<term><command>svn cat</command></term>
<listitem>
<para>Retrieves a file as it existed in a particular
revision number and displays it on your screen</para>
</listitem>
</varlistentry>

<varlistentry>
<term><command>svn list</command></term>
<listitem>
<para>Displays the files in a directory for any given
revision</para>
</listitem>
</varlistentry>

</variablelist>


<!-- =============================================================== -->
<sect2 id="svn.tour.history.log">
<title>Generating a List of Historical Changes</title>

<para>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&mdash;if it was provided&mdash;the log message that accompanied
the commit:</para>

<screen>
$ svn log
------------------------------------------------------------------------
r3 | sally | 2008-05-15 23:09:28 -0500 (Thu, 15 May 2008) | 1 line

Added include lines and corrected # of cheese slices.
------------------------------------------------------------------------
r2 | harry | 2008-05-14 18:43:15 -0500 (Wed, 14 May 2008) | 1 line

Added main() methods.
------------------------------------------------------------------------
r1 | sally | 2008-05-10 19:50:31 -0500 (Sat, 10 May 2008) | 1 line

Initial import
------------------------------------------------------------------------
</screen>

<para>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</option> (<option>-r</option>)
option:</para>

<screen>
$ svn log -r 5:19 # shows logs 5 through 19 in chronological order

$ svn log -r 19:5 # shows logs 5 through 19 in reverse order

$ svn log -r 8 # shows log for revision 8
</screen>

<para>You can also examine the log history of a single file or
directory. For example:</para>

<screen>
$ svn log foo.c
&hellip;
$ svn log http://foo.com/svn/trunk/code/foo.c
&hellip;
</screen>

<para>These will display log messages <emphasis>only</emphasis>
for those revisions in which the working file (or URL)
changed.</para>

<sidebar>

<title>Why Does svn log Not Show Me What I
Just Committed?</title>

<para>If you make a commit and immediately type <userinput>svn
log</userinput> with no arguments, you may notice that your
most recent commit doesn't show up in the list of log
messages. This is due to a combination of the behavior of
<command>svn commit</command> and the default behavior of
<command>svn log</command>. First, when you commit changes
to the repository, <command>svn</command> bumps only the
revision of files (and directories) that it commits, so
usually the parent directory remains at the older revision
(See
<xref linkend="svn.basic.in-action.mixedrevs.update-commit"/>
for an explanation of why). <command>svn log</command> then
defaults to fetching the history of the directory at its
current revision, and thus you don't see the newly committed
changes. The solution here is to either update your working
copy or explicitly provide a revision number to <command>svn
log</command> by using the <option>--revision</option>
(<option>-r</option>) option.</para>

</sidebar>

<para>If you want even more information about a file or
directory, <command>svn log</command> also takes a
<option>--verbose</option> (<option>-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:</para>

<screen>
$ svn log -r 8 -v
------------------------------------------------------------------------
r8 | sally | 2008-05-21 13:19:25 -0500 (Wed, 21 May 2008) | 1 line
Changed paths:
M /trunk/code/foo.c
M /trunk/code/bar.h
A /trunk/code/doc/README

Frozzled the sub-space winch.

------------------------------------------------------------------------
</screen>

<para>
<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.</para>

<sidebar>
<title>Why Does svn log Give Me an Empty
Response?</title>

<para>After working with Subversion for a bit, most users will
come across something like this:</para>

<screen>
$ svn log -r 2
------------------------------------------------------------------------
$
</screen>

<para>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 topmost URL of your repository, as in <userinput>svn log -r 2
http://svn.collab.net/repos/svn</userinput>.</para>

</sidebar>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.history.diff">
<title>Examining the Details of Historical Changes</title>

<para>We've already seen <command>svn diff</command>
before&mdash;it displays file differences in unified diff
format; we used it to show the local modifications made to
our working copy before committing to the repository.</para>

<para>In fact, it turns out that there are
<emphasis>three</emphasis> distinct uses of <command>svn
diff</command>:</para>

<itemizedlist>

<listitem>
<para>Examining local changes</para>
</listitem>

<listitem>
<para>Comparing your working copy to the repository</para>
</listitem>

<listitem>
<para>Comparing repository revisions</para>
</listitem>

</itemizedlist>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.history.diff.local">
<title>Examining local changes</title>

<para>As we've seen, invoking <userinput>svn diff</userinput> with
no options will compare your working files to the cached
<quote>pristine</quote> copies in
the <filename>.svn</filename> area:</para>

<screen>
$ svn diff
Index: rules.txt
===================================================================
--- rules.txt (revision 3)
+++ rules.txt (working copy)
@@ -1,4 +1,5 @@
Be kind to others
Freedom = Responsibility
Everything in moderation
-Chew with your mouth open
+Chew with your mouth closed
+Listen when others are speaking
$
</screen>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.history.diff.wcrepos">
<title>Comparing working copy to repository</title>

<para>If a single <option>--revision</option>
(<option>-r</option>) number is passed, your
working copy is compared to the specified revision in the
repository:</para>

<screen>
$ svn diff -r 3 rules.txt
Index: rules.txt
===================================================================
--- rules.txt (revision 3)
+++ rules.txt (working copy)
@@ -1,4 +1,5 @@
Be kind to others
Freedom = Responsibility
Everything in moderation
-Chew with your mouth open
+Chew with your mouth closed
+Listen when others are speaking
$
</screen>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.history.diff.reposrepos">
<title>Comparing repository revisions</title>

<para>If two revision numbers, separated by a colon, are
passed via <option>--revision</option>
(<option>-r</option>), the two revisions are directly
compared:</para>

<screen>
$ svn diff -r 2:3 rules.txt
Index: rules.txt
===================================================================
--- rules.txt (revision 2)
+++ rules.txt (revision 3)
@@ -1,4 +1,4 @@
Be kind to others
-Freedom = Chocolate Ice Cream
+Freedom = Responsibility
Everything in moderation
Chew with your mouth open
$
</screen>

<para>A more convenient way of comparing one revision to the
previous revision is to use the <option>--change</option>
(<option>-c</option>) option:</para>

<screen>
$ svn diff -c 3 rules.txt
Index: rules.txt
===================================================================
--- rules.txt (revision 2)
+++ rules.txt (revision 3)
@@ -1,4 +1,4 @@
Be kind to others
-Freedom = Chocolate Ice Cream
+Freedom = Responsibility
Everything in moderation
Chew with your mouth open
$
</screen>

<para>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:</para>

<screen>
$ svn diff -c 5 http://svn.example.com/repos/example/trunk/text/rules.txt
&hellip;
$
</screen>

</sect3>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.history.browsing">
<title>Browsing the Repository</title>

<para>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.</para>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.history.browsing.cat">
<title>svn cat</title>


<para>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>:</para>

<screen>
$ svn cat -r 2 rules.txt
Be kind to others
Freedom = Chocolate Ice Cream
Everything in moderation
Chew with your mouth open
$
</screen>

<para>You can also redirect the output directly into a
file:</para>

<screen>
$ svn cat -r 2 rules.txt &gt; rules.txt.v2
$
</screen>

</sect3>

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<sect3 id="svn.tour.history.browsing.list">
<title>svn list</title>

<para>The <command>svn list</command> command shows you what
files are in a repository directory without actually
downloading the files to your local machine:</para>

<screen>
$ svn list http://svn.collab.net/repos/svn
README
branches/
clients/
tags/
trunk/
</screen>

<para>If you want a more detailed listing, pass the
<option>--verbose</option> (<option>-v</option>) flag to get
output like this:</para>

<screen>
$ svn list -v http://svn.collab.net/repos/svn
20620 harry 1084 Jul 13 2006 README
23339 harry Feb 04 01:40 branches/
21282 sally Aug 27 09:41 developer-resources/
23198 harry Jan 23 17:17 tags/
23351 sally Feb 05 13:26 trunk/
</screen>

<para>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.</para>

<warning>
<para>The <userinput>svn list</userinput> 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 want a
listing of your local directory, you could use just plain
<command>ls</command> (or any reasonable non-Unixy
equivalent).</para>
</warning>

</sect3>

</sect2>

<!-- =============================================================== -->
<sect2 id="svn.tour.history.snapshots">
<title>Fetching Older Repository Snapshots</title>

<para>In addition to all of the previous 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>:
<footnote>
<para>See? We told you that Subversion was a time machine.</para>
</footnote>
</para>

<screen>
$ svn checkout -r 1729 # Checks out a new working copy at r1729
&hellip;
$ svn update -r 1729 # Updates an existing working copy to r1729
&hellip;
</screen>

<tip>
<para>Many Subversion newcomers attempt to use the preceding
<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.basicmerging.resurrect"/> for a
description of how to <quote>undo</quote> a commit.</para>
</tip>

<para>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,
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>:</para>

<screen>
$ svn export http://svn.example.com/svn/repos1 # Exports latest revision
&hellip;
$ svn export http://svn.example.com/svn/repos1 -r 1729
# Exports revision r1729
&hellip;
</screen>

</sect2>

</sect1>


<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.tour.cleanup">
<title>Sometimes You Just Need to Clean Up</title>

<para>Now that we've covered the day-to-day tasks that you'll
frequently use Subversion for, we'll review a few administrative
tasks relating to your working copy.</para>


<sect2 id="svn.tour.cleanup.disposal">

<title>Disposing of a Working Copy</title>

<para>Subversion doesn't track either the state or the existence of
working copies on the server, so there's no server overhead to
keeping working copies around. Likewise, there's no need to
let the server know that you're going to delete a working
copy.</para>

<para>If you're likely to use a working copy again, there's
nothing wrong with just leaving it on disk until you're ready
to use it again, at which point all it takes is an
<command>svn update</command> to bring it up to date and ready
for use.</para>

<para>However, if you're definitely not going to use a working
copy again, you can safely delete the entire thing, but you'd
be well served to take a look through the working copy for
unversioned files. To find these files, run <userinput>svn
status</userinput> and review any files that are prefixed with a
<literal>?</literal> to make certain that they're not of
importance. After you're done reviewing, you can safely
delete your working copy.</para>

</sect2>

<sect2 id="svn.tour.cleanup.interruption">

<title>Recovering from an Interruption</title>

<para>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 logfile. Next, it
executes the commands in the logfile to apply the requested
change, holding a lock on the relevant part of the working
copy while it works&mdash;to prevent other Subversion clients
from accessing the working copy mid-change. Finally,
Subversion removes the logfile. Architecturally, this is
similar to a journaled filesystem. If a Subversion operation
is interrupted (e.g, if the process is killed or if the machine
crashes), the logfiles remain on disk. By
reexecuting the logfiles, Subversion can complete the
previously started operation, and your working copy can get
itself back into a consistent state.</para>

<para>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> this is the command that you
should run. Also, <command>svn status</command> will display
an <literal>L</literal> next to locked items:</para>

<screen>
$ svn status
L somedir
M somedir/foo.c

$ svn cleanup
$ svn status
M somedir/foo.c
</screen>

<para>Don't confuse these working copy locks with the ordinary
locks that Subversion users create when using
the lock-modify-unlock model of concurrent
version control; see the sidebar
<xref linkend="svn.advanced.locking.meanings"/> for
clarification.</para>

</sect2>

</sect1>

<!-- ================================================================= -->
<!-- ================================================================= -->
<!-- ================================================================= -->
<sect1 id="svn.tour.summary">
<title>Summary</title>

<para>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 different commands that Subversion
has&mdash;and how you can use them to make your work
easier.</para>

</sect1>

</chapter>

<!--
local variables:
sgml-parent-document: ("book.xml" "chapter")
end:
-->
Show details Hide details

Change log

r3306 by cmpilato on Sep 15, 2008   Diff
Tag 1.5 version of the English book (also
known "Version Control With
Subversion, second edition", or "ISBN 10:
0-596-51033-0", or "ISBN 13:
9780596510336", or "Pilato's Bane", or
...)
Go to: 

Older revisions

r3301 by cmpilato on Sep 12, 2008   Diff
* src/en/book/ch00-preface.xml,
* src/en/book/ch03-advanced-
topics.xml,
* src/en/book/ch05-repository-
admin.xml,
...
r3291 by cmpilato on Sep 03, 2008   Diff
* src/en/book/ch02-basic-usage.xml
  Fix diff description problem -- it
can compare repository revisions,
  not compare two different
repositories with each other.
...
r3289 by cmpilato on Sep 03, 2008   Diff
* src/en/book/ch02-basic-usage.xml
  Rework some stuff to avoid talking
about "checking in", which is
  explicitly forbidden in our HACKING
document.  As a side-effect,
...
All revisions of this file

File info

Size: 90770 bytes, 2296 lines

File properties

svn:mime-type
text/xml
svn:eol-style
native
Hosted by Google Code