1 | .\" Format this file with: |
---|
2 | .\" pic file | tbl | troff -ms |
---|
3 | .\" |
---|
4 | .\" \*s stands for $, and avoids problems when this file is checked in. |
---|
5 | .ds s $ |
---|
6 | .de D( |
---|
7 | .DS |
---|
8 | .nr VS 12p |
---|
9 | .vs 12p |
---|
10 | .I |
---|
11 | .. |
---|
12 | .de D) |
---|
13 | .DE |
---|
14 | .nr VS 18p |
---|
15 | .vs 18p |
---|
16 | .R |
---|
17 | .. |
---|
18 | .de Id |
---|
19 | .ND \\$4 |
---|
20 | .. |
---|
21 | .Id $Id: rcs.ms,v 1.1.1.1 1996-10-04 05:52:39 ghudson Exp $ |
---|
22 | .RP |
---|
23 | .TL |
---|
24 | RCS\*-A System for Version Control |
---|
25 | .sp |
---|
26 | .AU |
---|
27 | Walter F. Tichy |
---|
28 | .AI |
---|
29 | Department of Computer Sciences |
---|
30 | Purdue University |
---|
31 | West Lafayette, Indiana 47907 |
---|
32 | .sp |
---|
33 | .AB |
---|
34 | An important problem in program development and maintenance is version control, |
---|
35 | i.e., the task of keeping a software system consisting of many versions and |
---|
36 | configurations well organized. |
---|
37 | The Revision Control System (RCS) |
---|
38 | is a software tool that assists with that task. |
---|
39 | RCS manages revisions of text documents, in particular source programs, |
---|
40 | documentation, and test data. |
---|
41 | It automates the storing, retrieval, logging and identification of revisions, |
---|
42 | and it provides selection mechanisms for composing configurations. |
---|
43 | This paper introduces basic version control concepts and |
---|
44 | discusses the practice of version control |
---|
45 | using RCS. |
---|
46 | For conserving space, RCS stores deltas, i.e., differences between |
---|
47 | successive revisions. Several delta storage methods are discussed. |
---|
48 | Usage statistics show that RCS's delta storage method is |
---|
49 | space and time efficient. |
---|
50 | The paper concludes with a detailed survey of version control tools. |
---|
51 | .sp |
---|
52 | \fBKeywords\fR: configuration management, history management, |
---|
53 | version control, revisions, deltas. |
---|
54 | .AE |
---|
55 | .FS |
---|
56 | An earlier version of this paper was published in |
---|
57 | .I "Software\*-Practice & Experience" |
---|
58 | .B 15 , |
---|
59 | 7 (July 1985), 637-654. |
---|
60 | .FE |
---|
61 | .nr VS 18p |
---|
62 | .LP |
---|
63 | .NH |
---|
64 | Introduction |
---|
65 | .PP |
---|
66 | Version control is the task of keeping software |
---|
67 | systems consisting of many versions and configurations well organized. |
---|
68 | The Revision Control System (RCS) is a set of UNIX |
---|
69 | commands that assist with that task. |
---|
70 | .PP |
---|
71 | RCS' primary function is to manage \fIrevision groups\fR. |
---|
72 | A revision group is a set of text documents, called \fIrevisions\fR, |
---|
73 | that evolved from each other. A new revision is |
---|
74 | created by manually editing an existing one. |
---|
75 | RCS organizes the revisions into an ancestral tree. The initial revision |
---|
76 | is the root of the tree, and the tree edges indicate |
---|
77 | from which revision a given one evolved. |
---|
78 | Besides managing individual revision groups, RCS provides |
---|
79 | flexible selection functions for composing configurations. |
---|
80 | RCS may be combined with MAKE\u1\d, |
---|
81 | resulting in a powerful package for version control. |
---|
82 | .PP |
---|
83 | RCS also offers facilities for |
---|
84 | merging updates with customer modifications, |
---|
85 | for distributed software development, and |
---|
86 | for automatic identification. |
---|
87 | Identification is the `stamping' |
---|
88 | of revisions and configurations with unique markers. |
---|
89 | These markers are akin to serial numbers, |
---|
90 | telling software maintainers unambiguously which configuration |
---|
91 | is before them. |
---|
92 | .PP |
---|
93 | RCS is designed for both production and experimental |
---|
94 | environments. |
---|
95 | In production environments, |
---|
96 | access controls detect update conflicts and prevent overlapping changes. |
---|
97 | In experimental environments, where strong controls are |
---|
98 | counterproductive, it is possible to loosen the controls. |
---|
99 | .PP |
---|
100 | Although RCS was originally intended for programs, it is useful for any |
---|
101 | text that is revised frequently and whose previous revisions must be |
---|
102 | preserved. RCS has been applied successfully to store the source |
---|
103 | text for drawings, VLSI layouts, documentation, specifications, |
---|
104 | test data, form letters and articles. |
---|
105 | .PP |
---|
106 | This paper discusses the practice of |
---|
107 | version control using RCS. |
---|
108 | It also introduces basic version control concepts, |
---|
109 | useful for clarifying current practice and designing similar systems. |
---|
110 | Revision groups of individual components are treated in the next three sections, |
---|
111 | and the extensions to configurations follow. |
---|
112 | Because of its size, a survey of version control tools |
---|
113 | appears at the end of the paper. |
---|
114 | .NH |
---|
115 | Getting started with RCS |
---|
116 | .PP |
---|
117 | Suppose a text file \fIf.c\fR is to be placed under control of RCS. |
---|
118 | Invoking the check-in command |
---|
119 | .D( |
---|
120 | ci f.c |
---|
121 | .D) |
---|
122 | creates a new revision group with the contents of |
---|
123 | \fIf.c\fR as the initial |
---|
124 | revision (numbered 1.1) |
---|
125 | and stores the group into the file \fIf.c,v\fR. |
---|
126 | Unless told otherwise, the command deletes \fIf.c\fR. |
---|
127 | It also asks for a description of the group. |
---|
128 | The description should state the common purpose of all revisions in the group, |
---|
129 | and becomes part of the group's documentation. |
---|
130 | All later check-in commands will ask for a log entry, |
---|
131 | which should summarize the changes made. |
---|
132 | (The first revision is assigned a default log message, |
---|
133 | which just records the fact that it is the initial revision.) |
---|
134 | .PP |
---|
135 | Files ending in \fI,v\fR |
---|
136 | are called \fIRCS files\fR (\fIv\fR stands for \fIv\fRersions); |
---|
137 | the others are called working files. |
---|
138 | To get back the working file \fIf.c\fR in the previous example, |
---|
139 | execute the check-out command: |
---|
140 | .D( |
---|
141 | co f.c |
---|
142 | .D) |
---|
143 | .R |
---|
144 | This command extracts the latest revision from |
---|
145 | the revision group \fIf.c,v\fR and writes |
---|
146 | it into \fIf.c\fR. |
---|
147 | The file \fIf.c\fR can now be edited and, when finished, |
---|
148 | checked back in with \fIci\fR: |
---|
149 | .D( |
---|
150 | ci f.c |
---|
151 | .D) |
---|
152 | \fICi\fR assigns number 1.2 to |
---|
153 | the new revision. |
---|
154 | If \fIci\fR complains with the message |
---|
155 | .D( |
---|
156 | ci error: no lock set by <login> |
---|
157 | .D) |
---|
158 | then the system administrator has decided to configure RCS for a |
---|
159 | production environment by enabling the `strict locking feature'. |
---|
160 | If this feature is enabled, all RCS files are initialized |
---|
161 | such that check-in operations require a lock on the previous revision |
---|
162 | (the one from which the current one evolved). |
---|
163 | Locking prevents overlapping modifications if several people work on the same file. |
---|
164 | If locking is required, the revision should |
---|
165 | have been locked during the check-out by using |
---|
166 | the option \fI\-l\fR: |
---|
167 | .D( |
---|
168 | co \-l f.c |
---|
169 | .D) |
---|
170 | Of course it is too late now for the check-out with locking, because |
---|
171 | \fIf.c\fR has already been changed; checking out the file again |
---|
172 | would overwrite the modifications. |
---|
173 | (To prevent accidental overwrites, \fIco\fR senses the presence |
---|
174 | of a working file and asks whether the user really intended to overwrite it. |
---|
175 | The overwriting check-out is sometimes useful for |
---|
176 | backing up to the previous revision.) |
---|
177 | To be able to proceed with the check-in in the present case, first execute |
---|
178 | .D( |
---|
179 | rcs \-l f.c |
---|
180 | .D) |
---|
181 | This command retroactively locks the latest revision, unless someone |
---|
182 | else locked it in the meantime. In this case, the two programmers |
---|
183 | involved have to negotiate whose |
---|
184 | modifications should take precedence. |
---|
185 | .PP |
---|
186 | If an RCS file is private, i.e., if only the owner of the file is expected |
---|
187 | to deposit revisions into it, the strict locking feature is unnecessary and |
---|
188 | may be disabled. |
---|
189 | If strict locking is disabled, |
---|
190 | the owner of the RCS file need not have a lock for check-in. |
---|
191 | For safety reasons, all others |
---|
192 | still do. Turning strict locking off and on is done with the commands: |
---|
193 | .D( |
---|
194 | rcs \-U f.c \fRand\fP rcs \-L f.c |
---|
195 | .D) |
---|
196 | These commands enable or disable the strict locking feature for each RCS file |
---|
197 | individually. |
---|
198 | The system administrator only decides whether strict locking is |
---|
199 | enabled initially. |
---|
200 | .PP |
---|
201 | To reduce the clutter in a working directory, all RCS files can be moved |
---|
202 | to a subdirectory with the name \fIRCS\fR. |
---|
203 | RCS commands look first into that directory for RCS files. |
---|
204 | All the commands presented above work |
---|
205 | with the \fIRCS\fR subdirectory without change.\(dg |
---|
206 | .FS \(dg |
---|
207 | Pairs of RCS and working files can actually be specified in 3 ways: |
---|
208 | a) both are given, b) only the working file is given, c) only the |
---|
209 | RCS file is given. |
---|
210 | If a pair is given, both files may have arbitrary path prefixes; |
---|
211 | RCS commands pair them up intelligently. |
---|
212 | .FE |
---|
213 | .PP |
---|
214 | It may be undesirable that \fIci\fR deletes the working file. |
---|
215 | For instance, sometimes one would like to save the current revision, |
---|
216 | but continue editing. |
---|
217 | Invoking |
---|
218 | .D( |
---|
219 | ci \-l f.c |
---|
220 | .D) |
---|
221 | checks in \fIf.c\fR as usual, but performs an additional |
---|
222 | check-out with locking afterwards. Thus, the working file does |
---|
223 | not disappear after the check-in. |
---|
224 | Similarly, the option |
---|
225 | \fI\-u\fR does a check-in followed by a check-out without |
---|
226 | locking. This option is useful if the file is needed for compilation after the check-in. |
---|
227 | Both options update the identification markers in the working file |
---|
228 | (see below). |
---|
229 | .PP |
---|
230 | Besides the operations \fIci\fR and \fIco\fR, RCS provides the following |
---|
231 | commands: |
---|
232 | .sp 0 |
---|
233 | .nr VS 12p |
---|
234 | .vs 12p |
---|
235 | .TS |
---|
236 | tab(%); |
---|
237 | li l. |
---|
238 | ident%extract identification markers |
---|
239 | rcs%change RCS file attributes |
---|
240 | rcsclean%remove unchanged working files (optional) |
---|
241 | rcsdiff%compare revisions |
---|
242 | rcsfreeze%record a configuration (optional) |
---|
243 | rcsmerge%merge revisions |
---|
244 | rlog%read log messages and other information in RCS files |
---|
245 | .TE |
---|
246 | A synopsis of these commands appears in the Appendix. |
---|
247 | .NH 2 |
---|
248 | Automatic Identification |
---|
249 | .PP |
---|
250 | RCS can stamp source and object code with special identification strings, |
---|
251 | similar to product and serial numbers. |
---|
252 | To obtain such identification, place the marker |
---|
253 | .D( |
---|
254 | \*sId\*s |
---|
255 | .D) |
---|
256 | into the text of a revision, for instance inside a comment. |
---|
257 | The check-out operation will replace this marker with a string of the form |
---|
258 | .D( |
---|
259 | \*sId: filename revisionnumber date time author state locker \*s |
---|
260 | .D) |
---|
261 | This string need never be touched, because \fIco\fR keeps it |
---|
262 | up to date automatically. |
---|
263 | To propagate the marker into object code, simply put |
---|
264 | it into a literal character string. In C, this is done as follows: |
---|
265 | .D( |
---|
266 | static char rcsid[] = \&"\*sId\*s\&"; |
---|
267 | .D) |
---|
268 | The command \fIident\fR extracts such markers from any file, in particular from |
---|
269 | object code. |
---|
270 | \fIIdent\fR helps to find out |
---|
271 | which revisions of which modules were used in a given program. |
---|
272 | It returns a complete and unambiguous component list, |
---|
273 | from which a copy of the program can be reconstructed. |
---|
274 | This facility is invaluable for program maintenance. |
---|
275 | .PP |
---|
276 | There are several additional identification markers, one for each component |
---|
277 | of \*sId\*s. |
---|
278 | The marker |
---|
279 | .D( |
---|
280 | \*sLog\*s |
---|
281 | .D) |
---|
282 | has a similar function. It accumulates |
---|
283 | the log messages that are requested during check-in. |
---|
284 | Thus, one can maintain the complete history of a revision directly inside it, |
---|
285 | by enclosing it in a comment. |
---|
286 | Figure 1 is an edited version of a log contained in revision 4.1 of |
---|
287 | the file \fIci.c\fR. The log appears at the beginning of the file, |
---|
288 | and makes it easy to determine what the recent modifications were. |
---|
289 | .sp |
---|
290 | .nr VS 12p |
---|
291 | .vs 12p |
---|
292 | .ne 18 |
---|
293 | .nf |
---|
294 | .in +0.5i |
---|
295 | /* |
---|
296 | .in +\w'/'u |
---|
297 | * \*sLog: ci.c,v \*s |
---|
298 | * Revision 4.1 1983/05/10 17:03:06 wft |
---|
299 | * Added option \-d and \-w, and updated assignment of date, etc. to new delta. |
---|
300 | * Added handling of default branches. |
---|
301 | * |
---|
302 | * Revision 3.9 1983/02/15 15:25:44 wft |
---|
303 | * Added call to fastcopy() to copy remainder of RCS file. |
---|
304 | * |
---|
305 | * Revision 3.8 1983/01/14 15:34:05 wft |
---|
306 | * Added ignoring of interrupts while new RCS file is renamed; |
---|
307 | * avoids deletion of RCS files by interrupts. |
---|
308 | * |
---|
309 | * Revision 3.7 1982/12/10 16:09:20 wft |
---|
310 | * Corrected checking of return code from diff. |
---|
311 | * An RCS file now inherits its mode during the first ci from the working file, |
---|
312 | * except that write permission is removed. |
---|
313 | */ |
---|
314 | .in 0 |
---|
315 | .ce 1 |
---|
316 | Figure 1. Log entries produced by the marker \*sLog\*s. |
---|
317 | .fi |
---|
318 | .nr VS 18p |
---|
319 | .vs 18p |
---|
320 | .sp 0 |
---|
321 | .LP |
---|
322 | Since revisions are stored in the form of differences, |
---|
323 | each log message is |
---|
324 | physically stored once, |
---|
325 | independent of the number of revisions present. |
---|
326 | Thus, the \*sLog\*s marker incurs negligible space overhead. |
---|
327 | .NH |
---|
328 | The RCS Revision Tree |
---|
329 | .PP |
---|
330 | RCS arranges revisions in an ancestral tree. |
---|
331 | The \fIci\fR command builds this tree; the auxiliary command \fIrcs\fR |
---|
332 | prunes it. |
---|
333 | The tree has a root revision, normally numbered 1.1, and successive revisions |
---|
334 | are numbered 1.2, 1.3, etc. The first field of a revision number |
---|
335 | is called the \fIrelease number\fR and the second one |
---|
336 | the \fIlevel number\fR. Unless given explicitly, |
---|
337 | the \fIci\fR command assigns a new revision number |
---|
338 | by incrementing the level number of the previous revision. |
---|
339 | The release number must be incremented explicitly, using the |
---|
340 | \fI\-r\fR option of \fIci\fR. |
---|
341 | Assuming there are revisions 1.1, 1.2, and 1.3 in the RCS file f.c,v, the command |
---|
342 | .D( |
---|
343 | ci \-r2.1 f.c \fRor\fP ci \-r2 f.c |
---|
344 | .D) |
---|
345 | assigns the number 2.1 to the new revision. |
---|
346 | Later check-ins without the \fI\-r\fR option will assign the numbers 2.2, 2.3, |
---|
347 | and so on. |
---|
348 | The release number should be incremented only at major transition points |
---|
349 | in the development, for instance when a new release of a software product has |
---|
350 | been completed. |
---|
351 | .NH 2 |
---|
352 | When are branches needed? |
---|
353 | .PP |
---|
354 | A young revision tree is slender: |
---|
355 | It consists of only one branch, called the trunk. |
---|
356 | As the tree ages, side branches may form. |
---|
357 | Branches are needed in the following 4 situations. |
---|
358 | .IP "\fITemporary fixes\fR" |
---|
359 | .sp 0 |
---|
360 | Suppose a tree has 5 revisions grouped in 2 releases, |
---|
361 | as illustrated in Figure 2. |
---|
362 | Revision 1.3, the last one of release 1, is in operation at customer sites, |
---|
363 | while release 2 is in active development. |
---|
364 | .ne 4 |
---|
365 | .PS 4i |
---|
366 | .ps -2 |
---|
367 | box "1.1" |
---|
368 | arrow |
---|
369 | box "1.2" |
---|
370 | arrow |
---|
371 | box "1.3" |
---|
372 | arrow |
---|
373 | box "2.1" |
---|
374 | arrow |
---|
375 | box "2.2" |
---|
376 | arrow dashed |
---|
377 | .ps +2 |
---|
378 | .PE |
---|
379 | .ce 1 |
---|
380 | Figure 2. A slender revision tree. |
---|
381 | .sp 0 |
---|
382 | Now imagine a customer requesting a fix of |
---|
383 | a problem in revision 1.3, although actual development has moved on |
---|
384 | to release 2. RCS does not permit an extra |
---|
385 | revision to be spliced in between 1.3 and 2.1, since that would not reflect |
---|
386 | the actual development history. Instead, create a branch |
---|
387 | at revision 1.3, and check in the fix on that branch. |
---|
388 | The first branch starting at 1.3 has number 1.3.1, and |
---|
389 | the revisions on that branch are numbered 1.3.1.1, 1.3.1.2, etc. |
---|
390 | The double numbering is needed to allow for another |
---|
391 | branch at 1.3, say 1.3.2. |
---|
392 | Revisions on the second branch would be numbered |
---|
393 | 1.3.2.1, 1.3.2.2, and so on. |
---|
394 | The following steps create |
---|
395 | branch 1.3.1 and add revision 1.3.1.1: |
---|
396 | .sp 0 |
---|
397 | .I |
---|
398 | .nr VS 12p |
---|
399 | .vs 12p |
---|
400 | .TS |
---|
401 | tab(%); |
---|
402 | l l l. |
---|
403 | %co \-r1.3 f.c% \*- check out revision 1.3 |
---|
404 | %edit f.c% \*- change it |
---|
405 | %ci \-r1.3.1 f.c% \*- check it in on branch 1.3.1 |
---|
406 | .TE |
---|
407 | .nr VS 18p |
---|
408 | .vs 18p |
---|
409 | .R |
---|
410 | This sequence of commands transforms the tree of Figure 2 into |
---|
411 | the one in Figure 3. |
---|
412 | Note that it may be necessary to incorporate the differences |
---|
413 | between 1.3 and 1.3.1.1 |
---|
414 | into a revision at level 2. The operation \fIrcsmerge\fR automates this |
---|
415 | process (see the Appendix). |
---|
416 | .ne 7 |
---|
417 | .PS 4i |
---|
418 | .ps -2 |
---|
419 | box "1.1" |
---|
420 | arrow |
---|
421 | box "1.2" |
---|
422 | arrow |
---|
423 | R13: box "1.3" |
---|
424 | arrow |
---|
425 | R21: box "2.1" |
---|
426 | arrow |
---|
427 | R22: box "2.2" |
---|
428 | arrow dashed |
---|
429 | line invis down from R21.s |
---|
430 | RB1: box "1.3.1.1" |
---|
431 | arrow dashed right from RB1.e |
---|
432 | arrow from R13.s to RB1.w |
---|
433 | .ps +2 |
---|
434 | .PE |
---|
435 | .ce 1 |
---|
436 | Figure 3. A revision tree with one side branch |
---|
437 | .sp |
---|
438 | .IP "\fIDistributed development and customer modifications\fR" |
---|
439 | .sp 0 |
---|
440 | Assume a situation as in Figure 2, where revision 1.3 is in operation |
---|
441 | at several customer sites, |
---|
442 | while release 2 is in development. |
---|
443 | Customer sites should use RCS to store the distributed software. |
---|
444 | However, customer modifications should not be placed on the same branch |
---|
445 | as the distributed source; instead, they should be placed on a side branch. |
---|
446 | When the next software distribution arrives, |
---|
447 | it should be appended to the trunk of |
---|
448 | the customer's RCS file, and the customer |
---|
449 | can then merge the local modifications back into the new release. |
---|
450 | In the above example, a |
---|
451 | customer's RCS file would contain the following tree, assuming |
---|
452 | that the customer has received revision 1.3, added his local modifications |
---|
453 | as revision 1.3.1.1, then received revision 2.4, and merged |
---|
454 | 2.4 and 1.3.1.1, resulting in 2.4.1.1. |
---|
455 | .ne 7 |
---|
456 | .PS 4i |
---|
457 | .ps -2 |
---|
458 | R13: box "1.3" |
---|
459 | line invis |
---|
460 | R21: box invis |
---|
461 | line invis |
---|
462 | R22: box invis |
---|
463 | line invis |
---|
464 | R24: box "2.4" |
---|
465 | line invis |
---|
466 | R25: box invis |
---|
467 | line invis |
---|
468 | arrow from R13.e to R24.w |
---|
469 | line invis down from R21.s |
---|
470 | RB1: box "1.3.1.1" |
---|
471 | arrow from R13.s to RB1.w |
---|
472 | right |
---|
473 | line invis down from R25.s |
---|
474 | RB2: box "2.4.1.1" |
---|
475 | arrow from R24.s to RB2.w |
---|
476 | .ps +2 |
---|
477 | .PE |
---|
478 | .ce 1 |
---|
479 | Figure 4. A customer's revision tree with local modifications. |
---|
480 | .sp 1 |
---|
481 | This approach is actually practiced in the CSNET project, |
---|
482 | where several universities and a company cooperate |
---|
483 | in developing a national computer network. |
---|
484 | .IP "\fIParallel development\fR" |
---|
485 | .sp 0 |
---|
486 | Sometimes it is desirable to explore an alternate design or |
---|
487 | a different implementation technique in parallel with the |
---|
488 | main line development. Such development |
---|
489 | should be carried out on a side branch. |
---|
490 | The experimental changes may later be moved into the main line, or abandoned. |
---|
491 | .IP "\fIConflicting updates\fR" |
---|
492 | .sp 0 |
---|
493 | A common occurrence is that one programmer |
---|
494 | has checked out a revision, but cannot complete the assignment |
---|
495 | for some reason. In the meantime, another person |
---|
496 | must perform another modification |
---|
497 | immediately. In that case, the second person should check-out the same revision, |
---|
498 | modify it, and check it in on a side branch, for later merging. |
---|
499 | .PP |
---|
500 | Every node in a revision tree consists of the following attributes: |
---|
501 | a revision number, a check-in date and time, the author's identification, |
---|
502 | a log entry, a state and the actual text. All these attributes |
---|
503 | are determined at the time the revision is checked in. |
---|
504 | The state attribute indicates the status of a revision. |
---|
505 | It is set automatically to `experimental' during check-in. |
---|
506 | A revision can later be promoted to a higher status, for example |
---|
507 | `stable' or `released'. The set of states is user-defined. |
---|
508 | .NH 2 |
---|
509 | Revisions are represented as deltas |
---|
510 | .PP |
---|
511 | For conserving space, RCS stores revisions in the form |
---|
512 | of deltas, i.e., as differences between revisions. |
---|
513 | The user interface completely hides this fact. |
---|
514 | .PP |
---|
515 | A delta is a sequence of edit commands that transforms one string |
---|
516 | into another. The deltas employed by RCS are line-based, which means |
---|
517 | that the only edit commands allowed are insertion and deletion of lines. |
---|
518 | If a single character in a line is changed, the |
---|
519 | edit scripts consider the entire line changed. |
---|
520 | The program \fIdiff\fR\u2\d |
---|
521 | produces a small, line-based delta between pairs of text files. |
---|
522 | A character-based edit script would take much longer to compute, |
---|
523 | and would not be significantly shorter. |
---|
524 | .PP |
---|
525 | Using deltas is a classical space-time tradeoff: deltas reduce the |
---|
526 | space consumed, but increase access time. |
---|
527 | However, a version control tool should impose as little delay |
---|
528 | as possible on programmers. |
---|
529 | Excessive delays discourage the use of version controls, |
---|
530 | or induce programmers to take shortcuts that compromise system integrity. |
---|
531 | To gain reasonably fast access time for both editing and compiling, |
---|
532 | RCS arranges deltas in the following way. |
---|
533 | The most recent revision on the trunk is stored intact. |
---|
534 | All other revisions on the trunk are stored as reverse deltas. |
---|
535 | A reverse delta describes how to go backward in the development history: |
---|
536 | it produces the desired revision if applied to the successor of that revision. |
---|
537 | This implementation has the advantage |
---|
538 | that extraction of the latest revision is a simple and fast copy |
---|
539 | operation. |
---|
540 | Adding a new revision to the trunk is also fast: \fIci\fR simply |
---|
541 | adds the new revision intact, replaces the previous |
---|
542 | revision with a reverse delta, and keeps the rest of the old deltas. |
---|
543 | Thus, \fIci\fR requires the computation |
---|
544 | of only one new delta. |
---|
545 | .PP |
---|
546 | Branches need special treatment. The naive solution would be to |
---|
547 | store complete copies for the tips of all branches. |
---|
548 | Clearly, this approach would cost too much space. Instead, |
---|
549 | RCS uses \fIforward\fR deltas for branches. Regenerating a revision |
---|
550 | on a side branch proceeds as follows. First, extract the latest revision |
---|
551 | on the trunk; secondly, apply reverse deltas until the fork revision for |
---|
552 | the branch is obtained; thirdly, apply forward deltas until the desired |
---|
553 | branch revision is reached. Figure 5 illustrates a tree with |
---|
554 | one side branch. Triangles pointing to the left and right represent |
---|
555 | reverse and forward deltas, respectively. |
---|
556 | .ne 8 |
---|
557 | .PS 4i |
---|
558 | .ps -2 |
---|
559 | define BD X [line invis $1 right .5; |
---|
560 | line up .3 then left .5 down .3 then right .5 down .3 then up .3] X |
---|
561 | |
---|
562 | define FD X [line invis $1 right .5; |
---|
563 | line left .5 down .3 then up .6 then right .5 down .3;] X |
---|
564 | |
---|
565 | right |
---|
566 | D11: BD(" 1.1") |
---|
567 | arrow right from D11.e |
---|
568 | D12: BD(" 1.2") |
---|
569 | arrow right from D12.e |
---|
570 | D13: BD(" 1.3") |
---|
571 | arrow right from D13.e |
---|
572 | D21: BD(" 2.1") |
---|
573 | arrow right from D21.e |
---|
574 | D22: box "2.2" |
---|
575 | line invis down from D21.s |
---|
576 | F1: FD("1.3.1.1 ") |
---|
577 | arrow from D13.se to F1.w |
---|
578 | arrow from F1.e right |
---|
579 | right |
---|
580 | F2: FD("1.3.1.2 ") |
---|
581 | .ps +2 |
---|
582 | .PE |
---|
583 | .ce 1 |
---|
584 | Figure 5. A revision tree with reverse and forward deltas. |
---|
585 | .sp 0 |
---|
586 | .PP |
---|
587 | Although implementing fast check-out for the latest trunk revision, |
---|
588 | this arrangement has the disadvantage that generation of other revisions |
---|
589 | takes time proportional to the number of deltas applied. For example, |
---|
590 | regenerating the branch tip in Figure 5 requires application of five |
---|
591 | deltas (including the initial one). Since usage statistics show that |
---|
592 | the latest trunk revision is the one that is retrieved in 95 per cent |
---|
593 | of all cases (see the section on usage statistics), biasing check-out time |
---|
594 | in favor of that revision results in significant savings. |
---|
595 | However, careful implementation of the delta application process is |
---|
596 | necessary to provide low retrieval overhead for other revisions, in |
---|
597 | particular for branch tips. |
---|
598 | .PP |
---|
599 | There are several techniques for delta application. |
---|
600 | The naive one is to pass each delta to a general-purpose text editor. |
---|
601 | A prototype of RCS invoked the UNIX editor \fIed\fR both |
---|
602 | for applying deltas and for expanding the identification markers. |
---|
603 | Although easy to implement, performance was poor, owing to the |
---|
604 | high start-up costs and excess generality of \fIed\fR. An intermediate |
---|
605 | version of RCS used a special-purpose, stream-oriented editor. |
---|
606 | This technique reduced the cost of applying a delta to the cost of |
---|
607 | checking out the latest trunk revision. The reason for this behavior |
---|
608 | is that each delta application involves a complete pass over |
---|
609 | the preceding revision. |
---|
610 | .PP |
---|
611 | However, there is a much better algorithm. Note that the deltas are |
---|
612 | line oriented and that most of the work of a stream editor involves |
---|
613 | copying unchanged lines from one revision to the next. A faster |
---|
614 | algorithm avoids unnecessary copying of character strings by using |
---|
615 | a \fIpiece table\fR. |
---|
616 | A piece table is a one-dimensional array, specifying how a given |
---|
617 | revision is `pieced together' from lines in the RCS file. |
---|
618 | Suppose piece table \fIPT\dr\u\fR represents revision \fIr\fR. |
---|
619 | Then \fIPT\dr\u[i]\fR contains the starting position of line \fIi\fR |
---|
620 | of revision \fIr\fR. |
---|
621 | Application of the next delta transforms piece table \fIPT\dr\u\fR |
---|
622 | into \fIPT\dr+1\u\fR. For instance, a delete command removes a |
---|
623 | series of entries from the piece table. An insertion command inserts |
---|
624 | new entries, moving the entries following the insertion point further down the |
---|
625 | array. The inserted entries point to the text lines in the delta. |
---|
626 | Thus, no I/O is involved except for reading the delta itself. When all |
---|
627 | deltas have been applied to the piece table, a sequential pass |
---|
628 | through the table looks up each line in the RCS file and copies it to |
---|
629 | the output file, updating identification markers at the same time. |
---|
630 | Of course, the RCS file must permit random access, since the copied |
---|
631 | lines are scattered throughout that file. Figure 6 illustrates an |
---|
632 | RCS file with two revisions and the corresponding piece tables. |
---|
633 | .ne 13 |
---|
634 | .sp 6 |
---|
635 | .ce 1 |
---|
636 | \fIFigure 6 is not available.\fP |
---|
637 | .sp 5 |
---|
638 | .ce 1 |
---|
639 | Figure 6. An RCS file and its piece tables |
---|
640 | .sp 0 |
---|
641 | .PP |
---|
642 | The piece table approach has the property that the time for applying a single |
---|
643 | delta is roughly determined by the size of the delta, and not by the |
---|
644 | size of the revision. For example, if a delta is |
---|
645 | 10 per cent of the size of a revision, then applying it takes only |
---|
646 | 10 per cent of the time to generate the latest trunk revision. (The stream |
---|
647 | editor would take 100 per cent.) |
---|
648 | .PP |
---|
649 | There is an important alternative for representing deltas that affects |
---|
650 | performance. SCCS\u3\d, |
---|
651 | a precursor of RCS, uses \fIinterleaved\fR deltas. |
---|
652 | A file containing interleaved deltas is partitioned into blocks of lines. |
---|
653 | Each block has a header that specifies to which revision(s) the block |
---|
654 | belongs. The blocks are sorted out in such a way that a single |
---|
655 | pass over the file can pick up all the lines belonging to a given |
---|
656 | revision. Thus, the regeneration time for all revisions is the same: |
---|
657 | all headers must be inspected, and the associated blocks either copied |
---|
658 | or skipped. As the number of revisions increases, the cost of retrieving |
---|
659 | any revision is much higher than the cost of checking out the |
---|
660 | latest trunk revision with reverse deltas. A detailed comparison |
---|
661 | of SCCS's interleaved deltas and RCS's reverse deltas can be found |
---|
662 | in Reference 4. |
---|
663 | This reference considers the version of RCS with the |
---|
664 | stream editor only. The piece table method improves performance |
---|
665 | further, so that RCS is always faster than SCCS, except if 10 |
---|
666 | or more deltas are applied. |
---|
667 | .PP |
---|
668 | Additional speed-up for both delta methods can be obtained by caching |
---|
669 | the most recently generated revision, as has been implemented in DSEE.\u5\d |
---|
670 | With caching, access time to frequently used revisions can approach normal file |
---|
671 | access time, at the cost of some additional space. |
---|
672 | .NH |
---|
673 | Locking: A Controversial Issue |
---|
674 | .PP |
---|
675 | The locking mechanism for RCS was difficult to design. |
---|
676 | The problem and its solution are first presented in their `pure' form, |
---|
677 | followed by a discussion of the complications |
---|
678 | caused by `real-world' considerations. |
---|
679 | .PP |
---|
680 | RCS must prevent two or more persons from depositing competing changes of the |
---|
681 | same revision. |
---|
682 | Suppose two programmers check out revision 2.4 and |
---|
683 | modify it. Programmer A checks in a revision before programmer B\&. |
---|
684 | Unfortunately, programmer B has not seen A's |
---|
685 | changes, so the effect is that A's changes are covered up by B's deposit. |
---|
686 | A's changes are not lost since all revisions |
---|
687 | are saved, but they are confined to a single revision.\(dd |
---|
688 | .FS \(dd |
---|
689 | Note that this problem is entirely different from the atomicity problem. |
---|
690 | Atomicity means that |
---|
691 | concurrent update operations on the same RCS file cannot be permitted, |
---|
692 | because that may result in inconsistent data. |
---|
693 | Atomic updates are essential (and implemented in RCS), |
---|
694 | but do not solve the conflict discussed here. |
---|
695 | .FE |
---|
696 | .PP |
---|
697 | This conflict is prevented in RCS by locking. |
---|
698 | Whenever someone intends to edit a revision (as opposed |
---|
699 | to reading or compiling it), the revision should be checked out |
---|
700 | and locked, |
---|
701 | using the \fI\-l\fR option on \fIco\fR. On subsequent check-in, |
---|
702 | \fIci\fR tests the lock and then removes it. |
---|
703 | At most one programmer at a time may |
---|
704 | lock a particular revision, and only this programmer may check in |
---|
705 | the succeeding revision. |
---|
706 | Thus, while a revision is locked, it is the exclusive responsibility |
---|
707 | of the locker. |
---|
708 | .PP |
---|
709 | An important maxim for software tools like RCS is that they must |
---|
710 | not stand in the way of making progress with a project. |
---|
711 | This consideration leads to several weakenings of the locking mechanism. |
---|
712 | First of all, even if a revision is locked, it can |
---|
713 | still be checked out. This is necessary if other people |
---|
714 | wish to compile or inspect the locked revision |
---|
715 | while the next one is in preparation. The only operations they |
---|
716 | cannot do are to lock the revision or to check in the succeeding one. Secondly, |
---|
717 | check-in operations on other branches in the RCS file are still possible; the |
---|
718 | locking of one revision does not affect any other revision. |
---|
719 | Thirdly, revisions are occasionally locked for a long period of time |
---|
720 | because a programmer is absent or otherwise unable to complete |
---|
721 | the assignment. If another programmer has to make a pressing change, |
---|
722 | there are the following three alternatives for making progress: |
---|
723 | a) find out who is holding the lock and ask that person to release it; |
---|
724 | b) check out the locked revision, modify it, check it |
---|
725 | in on a branch, and merge the changes later; |
---|
726 | c) break the lock. Breaking a lock leaves a highly visible |
---|
727 | trace, namely an electronic mail message that is sent automatically to the |
---|
728 | holder of the lock, recording the breaker and a commentary requested from him. |
---|
729 | Thus, breaking locks is tolerated under certain circumstances, |
---|
730 | but will not go unnoticed. |
---|
731 | Experience has shown that the automatic mail message attaches a high enough |
---|
732 | stigma to lock breaking, |
---|
733 | such that programmers break locks only in real emergencies, |
---|
734 | or when a co-worker resigns and leaves locked revisions behind. |
---|
735 | .PP |
---|
736 | If an RCS file is private, i.e., when a programmer owns an RCS file |
---|
737 | and does not expect anyone else to perform check-in operations, |
---|
738 | locking is an unnecessary nuisance. |
---|
739 | In this case, |
---|
740 | the `strict locking feature' discussed earlier may be disabled, |
---|
741 | provided that file protection |
---|
742 | is set such that only the owner may write the RCS file. |
---|
743 | This has the effect that only the owner can check-in revisions, |
---|
744 | and that no lock is needed for doing so. |
---|
745 | .PP |
---|
746 | As added protection, |
---|
747 | each RCS file contains an access list that specifies the users |
---|
748 | who may execute update operations. If an access list is empty, |
---|
749 | only normal UNIX file protection applies. Thus, the access list is |
---|
750 | useful for restricting the set of people who would otherwise have update |
---|
751 | permission. Just as with locking, the access list |
---|
752 | has no effect on read-only operations such as \fIco\fR. This approach |
---|
753 | is consistent with the UNIX philosophy of openness, which contributes |
---|
754 | to a productive software development environment. |
---|
755 | .NH |
---|
756 | Configuration Management |
---|
757 | .PP |
---|
758 | The preceding sections described how RCS deals with revisions of individual |
---|
759 | components; this section discusses how to handle configurations. |
---|
760 | A configuration is a set of revisions, where each revision comes |
---|
761 | from a different revision group, and the revisions are selected |
---|
762 | according to a certain criterion. |
---|
763 | For example, |
---|
764 | in order to build a functioning compiler, the `right' |
---|
765 | revisions from the scanner, the parser, the optimizer |
---|
766 | and the code generator must be combined. |
---|
767 | RCS, in conjunction with MAKE, |
---|
768 | provides a number of facilities to effect a smooth selection. |
---|
769 | .NH 2 |
---|
770 | RCS Selection Functions |
---|
771 | .PP |
---|
772 | .IP "\fIDefault selection\fR" |
---|
773 | .sp 0 |
---|
774 | During development, the usual selection criterion is to choose |
---|
775 | the latest revision of all components. The \fIco\fR command |
---|
776 | makes this selection by default. For example, the command |
---|
777 | .D( |
---|
778 | co *,v |
---|
779 | .D) |
---|
780 | retrieves the latest revision on the default branch of each RCS file |
---|
781 | in the current directory. |
---|
782 | The default branch is usually the trunk, but may be |
---|
783 | set to be a side branch. |
---|
784 | Side branches as defaults are needed in distributed software development, |
---|
785 | as discussed in the section on the RCS revision tree. |
---|
786 | .sp |
---|
787 | .IP "\fIRelease based selection\fR" |
---|
788 | .sp 0 |
---|
789 | Specifying a release or branch number selects the latest revision in |
---|
790 | that release or branch. |
---|
791 | For instance, |
---|
792 | .D( |
---|
793 | co \-r2 *,v |
---|
794 | .D) |
---|
795 | retrieves the latest revision with release number 2 from each RCS file. |
---|
796 | This selection is convenient if a release has been completed and |
---|
797 | development has moved on to the next release. |
---|
798 | .sp |
---|
799 | .IP "\fIState and author based selection\fR" |
---|
800 | .sp 0 |
---|
801 | If the highest level number within a given release number |
---|
802 | is not the desired one, |
---|
803 | the state attribute can help. For example, |
---|
804 | .D( |
---|
805 | co \-r2 \-sReleased *,v |
---|
806 | .D) |
---|
807 | retrieves the latest revision with release number 2 whose state attribute |
---|
808 | is `Released'. |
---|
809 | Of course, the state attribute has to be set appropriately, using the |
---|
810 | \fIci\fR or \fIrcs\fR commands. |
---|
811 | Another alternative is to select a revision by its author, |
---|
812 | using the \fI\-w\fR option. |
---|
813 | .sp |
---|
814 | .IP "\fIDate based selection\fR" |
---|
815 | .sp 0 |
---|
816 | Revisions may also be selected by date. |
---|
817 | Suppose a release of an entire system was |
---|
818 | completed and current on March 4, at 1:00 p.m. local time. Then the command |
---|
819 | .D( |
---|
820 | co \-d'March 4, 1:00 pm LT' *,v |
---|
821 | .D) |
---|
822 | checks out all the components of that release, independent of the numbering. |
---|
823 | The \fI\-d\fR option specifies a `cutoff date', i.e., |
---|
824 | the revision selected has a check-in date that |
---|
825 | is closest to, but not after the date given. |
---|
826 | .IP "\fIName based selection\fR" |
---|
827 | .sp 0 |
---|
828 | The most powerful selection function is based on assigning symbolic |
---|
829 | names to revisions and branches. |
---|
830 | In large systems, a single release number or date is not sufficient |
---|
831 | to collect the appropriate revisions from all groups. |
---|
832 | For example, suppose one wishes to combine release 2 |
---|
833 | of one subsystem and release 15 of another. |
---|
834 | Most likely, the creation dates of those releases differ also. |
---|
835 | Thus, a single revision number or date passed to the \fIco\fR command |
---|
836 | will not suffice to select the right revisions. |
---|
837 | Symbolic revision numbers solve this problem. |
---|
838 | Each RCS file may contain a set of symbolic names that are mapped |
---|
839 | to numeric revision numbers. For example, assume |
---|
840 | the symbol \fIV3\fR is bound to release number 2 in file \fIs,v\fR, and to |
---|
841 | revision number 15.9 in \fIt,v\fR. |
---|
842 | Then the single command |
---|
843 | .D( |
---|
844 | co \-rV3 s,v t,v |
---|
845 | .D) |
---|
846 | retrieves the latest revision of release 2 from \fIs,v\fR, |
---|
847 | and revision 15.9 from \fIt,v\fR. |
---|
848 | In a large system with many modules, checking out all |
---|
849 | revisions with one command greatly simplifies configuration management. |
---|
850 | .PP |
---|
851 | Judicious use of symbolic revision numbers helps with organizing |
---|
852 | large configurations. |
---|
853 | A special command, \fIrcsfreeze\fR, |
---|
854 | assigns a symbolic revision number to a selected revision |
---|
855 | in every RCS file. |
---|
856 | \fIRcsfreeze\fR effectively freezes a configuration. |
---|
857 | The assigned symbolic revision number selects all components |
---|
858 | of the configuration. |
---|
859 | If necessary, symbolic numbers |
---|
860 | may even be intermixed with numeric ones. Thus, \fIV3.5\fR in the |
---|
861 | above example |
---|
862 | would select revision 2.5 in \fIs,v\fR and branch 15.9.5 in \fIt,v\fR. |
---|
863 | .PP |
---|
864 | The options \fI\-r\fR, \fI\-s\fR, \fI\-w\fR and \fI\-d\fR |
---|
865 | may be combined. If a branch is given, the latest revision |
---|
866 | on that branch satisfying all conditions is retrieved; |
---|
867 | otherwise, the default branch is used. |
---|
868 | .NH 2 |
---|
869 | Combining MAKE and RCS |
---|
870 | .PP |
---|
871 | MAKE\u1\d |
---|
872 | is a program that processes configurations. |
---|
873 | It is driven by configuration specifications |
---|
874 | recorded in a special file, called a `Makefile'. |
---|
875 | MAKE avoids redundant processing steps |
---|
876 | by comparing creation dates of source and processed objects. |
---|
877 | For example, when instructed to compile all |
---|
878 | modules of a given system, it only recompiles |
---|
879 | those source modules that were changed |
---|
880 | since they were processed last. |
---|
881 | .PP |
---|
882 | MAKE has been extended with an auto-checkout feature for RCS.* |
---|
883 | .FS * |
---|
884 | This auto-checkout extension is available only in some versions of MAKE, |
---|
885 | e.g. GNU MAKE. |
---|
886 | .FE |
---|
887 | When a certain file to be processed is not present, |
---|
888 | MAKE attempts a check-out operation. |
---|
889 | If successful, MAKE performs the required processing, and then deletes |
---|
890 | the checked out file to conserve space. |
---|
891 | The selection parameters discussed above can be passed to MAKE |
---|
892 | either as parameters, or directly embedded in the Makefile. |
---|
893 | MAKE has also been extended to search the subdirectory named \fIRCS\fR |
---|
894 | for needed files, rather than just the current working directory. |
---|
895 | However, if a working file is present, MAKE totally ignores the corresponding |
---|
896 | RCS file and uses the working file. |
---|
897 | (In newer versions of MAKE distributed by AT&T and others, |
---|
898 | auto-checkout can be |
---|
899 | achieved with the rule DEFAULT, instead of a special extension of MAKE. |
---|
900 | However, a file checked out by the rule DEFAULT |
---|
901 | will not be deleted after processing. \fIRcsclean\fR can be |
---|
902 | used for that purpose.) |
---|
903 | .PP |
---|
904 | With auto-checkout, RCS/MAKE can effect a selection rule |
---|
905 | especially tuned for multi-person software development and maintenance. |
---|
906 | In these situations, |
---|
907 | programmers should obtain configurations that consist of |
---|
908 | the revisions they have personally checked out plus the latest |
---|
909 | checked in revision of all other revision groups. |
---|
910 | This schema can be set up as follows. |
---|
911 | .PP |
---|
912 | Each programmer chooses a working directory |
---|
913 | and places into it a symbolic link, named \fIRCS\fR, |
---|
914 | to the directory containing the relevant RCS files. |
---|
915 | The symbolic link makes sure that \fIco\fR and \fIci\fR |
---|
916 | operations need only specify the working files, and that |
---|
917 | the Makefile need not be changed. |
---|
918 | The programmer then checks out the needed files and modifies them. |
---|
919 | If MAKE is invoked, |
---|
920 | it composes configurations by selecting those |
---|
921 | revisions that are checked out, and the rest from the |
---|
922 | subdirectory \fIRCS\fR. |
---|
923 | The latter selection may be controlled by a symbolic |
---|
924 | revision number or any of the other selection criteria. |
---|
925 | If there are several programmers editing in separate working directories, |
---|
926 | they are insulated from each other's changes until checking in their |
---|
927 | modifications. |
---|
928 | .PP |
---|
929 | Similarly, a maintainer can recreate an older configuration |
---|
930 | by starting to work in an empty working directory. |
---|
931 | During the initial MAKE invocation, all revisions are selected from RCS files. |
---|
932 | As the maintainer checks out files and modifies them, |
---|
933 | a new configuration is gradually built up. |
---|
934 | Every time MAKE is invoked, it substitutes the modified revisions |
---|
935 | into the configuration being manipulated. |
---|
936 | .PP |
---|
937 | A final application of RCS is to use it for storing Makefiles. |
---|
938 | Revision groups of Makefiles represent |
---|
939 | multiple versions of configurations. |
---|
940 | Whenever a configuration is baselined or distributed, |
---|
941 | the best approach is to unambiguously fix |
---|
942 | the configuration with a symbolic revision number by calling |
---|
943 | \fIrcsfreeze\fR, |
---|
944 | to embed that symbol into the Makefile, and to |
---|
945 | check in the Makefile (using the same symbolic revision number). |
---|
946 | With this approach, old configurations |
---|
947 | can be regenerated easily and reliably. |
---|
948 | .NH |
---|
949 | Usage Statistics |
---|
950 | .PP |
---|
951 | The following usage statistics were collected on two DEC VAX-11/780 |
---|
952 | computers of the Purdue Computer Science Department. Both machines |
---|
953 | are mainly used for research purposes. Thus, the data |
---|
954 | reflect an environment in which the majority of projects |
---|
955 | involve prototyping and advanced software development, |
---|
956 | but relatively little long-term maintenance. |
---|
957 | .PP |
---|
958 | For the first experiment, |
---|
959 | the \fIci\fR and \fIco\fR operations were instrumented |
---|
960 | to log the number of backward and forward deltas applied. |
---|
961 | The data were collected during a 13 month period |
---|
962 | from Dec. 1982 to Dec. 1983. |
---|
963 | Table I summarizes the results. |
---|
964 | .sp 0 |
---|
965 | .nr VS 12p |
---|
966 | .vs 12p |
---|
967 | .TS |
---|
968 | center,box,tab(#); |
---|
969 | c|c|c|c|c s|c s |
---|
970 | c|c|c|c|c s|c s |
---|
971 | l|n|n|n|n n|n n. |
---|
972 | Operation#Total#Total deltas#Mean deltas#Operations#Branch |
---|
973 | #operations #applied#applied#with >1 delta#operations |
---|
974 | _ |
---|
975 | co # 7867# 9320#1.18#509#(6%)#203#(3%) |
---|
976 | ci # 3468# 2207#0.64# 85#(2%)# 75#(2%) |
---|
977 | ci & co#11335#11527#1.02#594#(5%)#278#(2%) |
---|
978 | .TE |
---|
979 | .ce 1 |
---|
980 | Table I. Statistics for \fIco\fR and \fIci\fR operations. |
---|
981 | .nr VS 18p |
---|
982 | .vs 18p |
---|
983 | .PP |
---|
984 | The first two lines show statistics for check-out and check-in; |
---|
985 | the third line shows the combination. |
---|
986 | Recall that \fIci\fR performs an implicit check-out to obtain |
---|
987 | a revision for computing the delta. |
---|
988 | In all measures presented, the most recent revision (stored intact) |
---|
989 | counts as one delta. The number of deltas applied represents |
---|
990 | the number of passes necessary, where the first `pass' is a copying step. |
---|
991 | .PP |
---|
992 | Note that the check-out operation is executed more than |
---|
993 | twice as frequently as the check-in operation. |
---|
994 | The fourth column gives the mean number of deltas |
---|
995 | applied in all three cases. |
---|
996 | For \fIci\fR, the mean number of deltas applied is less |
---|
997 | than one. |
---|
998 | The reasons are that the initial check-in requires no delta at all, and that |
---|
999 | the only time \fIci\fR requires more than one delta is for branches. |
---|
1000 | Column 5 shows the actual number of operations that applied more than one |
---|
1001 | delta. |
---|
1002 | The last column indicates that branches were not used often. |
---|
1003 | .PP |
---|
1004 | The last three columns demonstrate that the most recent trunk revision |
---|
1005 | is by far the most frequently accessed. |
---|
1006 | For RCS, check-out of |
---|
1007 | this revision is a simple copy operation, which is the absolute minimum |
---|
1008 | given the copy-semantics of \fIco\fR. |
---|
1009 | Access to older revisions and branches |
---|
1010 | is more common in non-academic environments, |
---|
1011 | yet even if access to older deltas were an order |
---|
1012 | of magnitude more frequent, |
---|
1013 | the combined average number of deltas applied would still be below 1.2. |
---|
1014 | Since RCS is faster than SCCS until up to 10 delta applications, |
---|
1015 | reverse deltas are clearly the method of choice. |
---|
1016 | .PP |
---|
1017 | The second experiment, conducted in March of 1984, |
---|
1018 | involved surveying the existing RCS files |
---|
1019 | on our two machines. The goal was to determine the mean number of |
---|
1020 | revisions per RCS file, as well as the space consumed by them. |
---|
1021 | Table II shows the results. (Tables I and II were produced at different |
---|
1022 | times and are unrelated.) |
---|
1023 | .sp 0 |
---|
1024 | .nr VS 12p |
---|
1025 | .vs 12p |
---|
1026 | .TS |
---|
1027 | center,box,tab(#); |
---|
1028 | c | c | c | c | c | c | c |
---|
1029 | c | c | c | c | c | c | c |
---|
1030 | l | n | n | n | n | n | n. |
---|
1031 | #Total RCS#Total#Mean#Mean size of#Mean size of#Overhead |
---|
1032 | #files#revisions#revisions#RCS files#revisions |
---|
1033 | _ |
---|
1034 | All files #8033#11133#1.39#6156#5585#1.10 |
---|
1035 | Files with#1477# 4578#3.10#8074#6041#1.34 |
---|
1036 | \(>= 2 deltas |
---|
1037 | .TE |
---|
1038 | .ce 1 |
---|
1039 | Table II. Statistics for RCS files. |
---|
1040 | .nr VS 18p |
---|
1041 | .vs 18p |
---|
1042 | .PP |
---|
1043 | The mean number of revisions per RCS file is 1.39. |
---|
1044 | Columns 5 and 6 show the mean sizes (in bytes) of an RCS file |
---|
1045 | and of the latest revision of each RCS file, respectively. |
---|
1046 | The `overhead' column contains the ratio of the mean sizes. |
---|
1047 | Assuming that all revisions in an RCS file are approximately the same size, |
---|
1048 | this ratio gives a measure of the space consumed by the extra revisions. |
---|
1049 | .PP |
---|
1050 | In our sample, over 80 per cent of the RCS files contained only a single revision. |
---|
1051 | The reason is that our |
---|
1052 | systems programmers routinely check in all source files |
---|
1053 | on the distribution tapes, even though they may never touch them again. |
---|
1054 | To get a better indication of how much space savings are possible |
---|
1055 | with deltas, all measures with those files |
---|
1056 | that contained 2 or more revisions were recomputed. Only for those files |
---|
1057 | is RCS necessary. |
---|
1058 | As shown in the second line, the average number of revisions for those files is |
---|
1059 | 3.10, with an overhead of 1.34. This means that the extra 2.10 deltas |
---|
1060 | require 34 per cent extra space, or |
---|
1061 | 16 per cent per extra revision. |
---|
1062 | Rochkind\u3\d |
---|
1063 | measured the space consumed by SCCS, and |
---|
1064 | reported an average of 5 revisions per group |
---|
1065 | and an overhead of 1.37 (or about 9 per cent per extra revision). |
---|
1066 | In a later paper, Glasser\u6\d |
---|
1067 | observed an average of 7 revisions per group in a single, large project, |
---|
1068 | but provided no overhead figure. |
---|
1069 | In his paper on DSEE\u5\d, |
---|
1070 | Leblang reported that delta storage combined with blank compression |
---|
1071 | results in an overhead of a mere 1\-2 per cent per revision. |
---|
1072 | Since leading blanks accounted for about 20 per cent of the surveyed Pascal |
---|
1073 | programs, a revision group with 5\-10 members was smaller |
---|
1074 | than a single cleartext copy. |
---|
1075 | .PP |
---|
1076 | The above observations demonstrate clearly that the space needed |
---|
1077 | for extra revisions is small. With delta storage, the luxury of |
---|
1078 | keeping multiple revisions online is certainly affordable. |
---|
1079 | In fact, introducing a system with delta storage may reduce |
---|
1080 | storage requirements, because programmers often save back-up copies |
---|
1081 | anyway. Since back-up copies are stored much more efficiently with deltas, |
---|
1082 | introducing a system such as RCS may |
---|
1083 | actually free a considerable amount of space. |
---|
1084 | .NH |
---|
1085 | Survey of Version Control Tools |
---|
1086 | .PP |
---|
1087 | The need to keep back-up copies of software arose when |
---|
1088 | programs and data were no longer stored on paper media, but were entered |
---|
1089 | from terminals and stored on disk. |
---|
1090 | Back-up copies are desirable for reliability, and many modern editors |
---|
1091 | automatically save a back-up copy for every file touched. |
---|
1092 | This strategy |
---|
1093 | is valuable for short-term back-ups, but not suitable for long-term |
---|
1094 | version control, since an existing back-up copy is overwritten whenever the |
---|
1095 | corresponding file is edited. |
---|
1096 | .PP |
---|
1097 | Tape archives are suitable for long-term, offline storage. |
---|
1098 | If all changed files are dumped on a back-up tape once per day, old revisions |
---|
1099 | remain accessible. However, tape archives are unsatisfactory |
---|
1100 | for version control in several ways. First, backing up the file |
---|
1101 | system every 24 hours does not capture intermediate revisions. |
---|
1102 | Secondly, the old revisions are not online, |
---|
1103 | and accessing them is tedious and time-consuming. |
---|
1104 | In particular, it is impractical to |
---|
1105 | compare several old revisions of a group, |
---|
1106 | because that may require mounting and searching several tapes. |
---|
1107 | Tape archives are important fail-safe tools in the |
---|
1108 | event of catastrophic disk failures or accidental deletions, |
---|
1109 | but they are ill-suited for version control. |
---|
1110 | Conversely, version control tools do not obviate the |
---|
1111 | need for tape archives. |
---|
1112 | .PP |
---|
1113 | A natural technique for keeping several old revisions online is |
---|
1114 | to never delete a file. |
---|
1115 | Editing a file |
---|
1116 | simply creates a new file with the same |
---|
1117 | name, but with a different sequence number. |
---|
1118 | This technique, available as an option in DEC's VMS operating system, |
---|
1119 | turns out to be inadequate for version control. |
---|
1120 | First, it is prohibitively expensive in terms of storage costs, |
---|
1121 | especially since no data compression techniques are employed. |
---|
1122 | Secondly, indiscriminately storing every change produces too many |
---|
1123 | revisions, and programmers have difficulties distinguishing them. |
---|
1124 | The proliferation of revisions forces programmers to spend much time on |
---|
1125 | finding and deleting useless files. |
---|
1126 | Thirdly, most of the support functions like locking, logging, |
---|
1127 | revision selection, |
---|
1128 | and identification described in this paper are not available. |
---|
1129 | .PP |
---|
1130 | An alternative approach is to separate editing from revision control. |
---|
1131 | The user may repeatedly edit a given revision, |
---|
1132 | until freezing it with an explicit command. |
---|
1133 | Once a revision is frozen, it is stored permanently and can no longer be modified. |
---|
1134 | (In RCS, freezing a revisions is done with \fIci\fR.) |
---|
1135 | Editing a frozen revision implicitly creates a new one, which |
---|
1136 | can again be changed repeatedly until it is frozen itself. |
---|
1137 | This approach saves exactly those revisions that the user |
---|
1138 | considers important, and keeps the number of revisions manageable. |
---|
1139 | IBM's CLEAR/CASTER\u7\d, |
---|
1140 | AT&T's SCCS\u3\d, |
---|
1141 | CMU's SDC\u8\d |
---|
1142 | and DEC's CMS\u9\d, |
---|
1143 | are examples of version control systems using this approach. |
---|
1144 | CLEAR/CASTER maintains a data base of programs, specifications, |
---|
1145 | documentation and messages, using deltas. |
---|
1146 | Its goal is to provide control over the development process from a |
---|
1147 | management viewpoint. |
---|
1148 | SCCS stores multiple revisions of source text in an ancestral tree, |
---|
1149 | records a log entry for each revision, |
---|
1150 | provides access control, and has facilities |
---|
1151 | for uniquely identifying each revision. |
---|
1152 | An efficient delta technique |
---|
1153 | reduces the space consumed by each revision group. |
---|
1154 | SDC is much simpler than SCCS because it stores not more than |
---|
1155 | two revisions. However, it maintains a complete log for all old |
---|
1156 | revisions, some of which may be on back-up tape. |
---|
1157 | CMS, like SCCS, manages tree-structured revision groups, |
---|
1158 | but offers no identification mechanism. |
---|
1159 | .PP |
---|
1160 | Tools for dealing with configurations are still in a state of flux. |
---|
1161 | SCCS, SDC and CMS can be combined with MAKE or MAKE-like programs. |
---|
1162 | Since flexible selection rules are missing from all these tools, |
---|
1163 | it is sometimes difficult |
---|
1164 | to specify precisely which revision of each group |
---|
1165 | should be passed to MAKE for building a desired configuration. |
---|
1166 | The Xerox Cedar system\u10\d |
---|
1167 | provides a `System Modeller' that can rebuild |
---|
1168 | a configuration from an arbitrary set of module revisions. |
---|
1169 | The revisions of a module are only distinguished by creation time, |
---|
1170 | and there is no tool for managing groups. |
---|
1171 | Since the selection rules are primitive, |
---|
1172 | the System Modeller appears to be somewhat tedious to use. |
---|
1173 | Apollo's DSEE\u5\d |
---|
1174 | is a sophisticated software engineering environment. |
---|
1175 | It manages revision groups in a way similar to SCCS and CMS. Configurations |
---|
1176 | are built using `configuration threads'. |
---|
1177 | A configuration thread states which revision of each group |
---|
1178 | named in a configuration should be chosen. |
---|
1179 | A configuration thread may contain dynamic specifiers |
---|
1180 | (e.g., `choose the revisions I am currently working on, |
---|
1181 | and the most recent revisions otherwise'), which are bound |
---|
1182 | automatically at build time. |
---|
1183 | It also provides a notification mechanism for alerting |
---|
1184 | maintainers about the need to rebuild a system after a change. |
---|
1185 | .PP |
---|
1186 | RCS is based on a general model for describing |
---|
1187 | multi-version/multi-configuration systems\u11\d. |
---|
1188 | The model describes systems using AND/OR graphs, where AND nodes represent |
---|
1189 | configurations, and OR nodes represent version groups. |
---|
1190 | The model gives rise to a suit of selection rules for |
---|
1191 | composing configurations, almost all of which are implemented in RCS. |
---|
1192 | The revisions selected by RCS are passed to MAKE for configuration building. |
---|
1193 | Revision group management is modelled after SCCS. |
---|
1194 | RCS retains SCCS's best features, |
---|
1195 | but offers a significantly simpler user interface, |
---|
1196 | flexible selection rules, adequate integration with MAKE |
---|
1197 | and improved identification. |
---|
1198 | A detailed comparison of RCS and SCCS appears in Reference 4. |
---|
1199 | .PP |
---|
1200 | An important component of all revision control systems |
---|
1201 | is a program for computing deltas. |
---|
1202 | SCCS and RCS use the program \fIdiff\fR\u2\d, |
---|
1203 | which first computes the longest common substring of two |
---|
1204 | revisions, and then produces the delta from that substring. |
---|
1205 | The delta is simply an edit script consisting of deletion and |
---|
1206 | insertion commands that generate one revision from the other. |
---|
1207 | .PP |
---|
1208 | A delta based on a longest common substring is not necessarily minimal, |
---|
1209 | because it does not take advantage of crossing block moves. |
---|
1210 | Crossing block moves arise if two or more blocks of lines |
---|
1211 | (e.g., procedures) |
---|
1212 | appear in a different order in two revisions. |
---|
1213 | An edit script derived from a longest common substring |
---|
1214 | first deletes the shorter of the two blocks, and then reinserts it. |
---|
1215 | Heckel\u12\d |
---|
1216 | proposed an algorithm for detecting block moves, but |
---|
1217 | since the algorithm is based on heuristics, |
---|
1218 | there are conditions |
---|
1219 | under which the generated delta is far from minimal. |
---|
1220 | DSEE uses this algorithm combined with blank compression, |
---|
1221 | apparently with satisfactory overall results. |
---|
1222 | A new algorithm that is guaranteed to produce a minimal delta based on |
---|
1223 | block moves appears in Reference 13. |
---|
1224 | A future release of RCS will use this algorithm. |
---|
1225 | .PP |
---|
1226 | \fIAcknowledgements\fR: |
---|
1227 | Many people have helped make RCS a success by contributed criticisms, suggestions, |
---|
1228 | corrections, and even whole new commands (including manual pages). |
---|
1229 | The list of people is too long to be |
---|
1230 | reproduced here, but my sincere thanks for their help and |
---|
1231 | goodwill goes to all of them. |
---|
1232 | .sp |
---|
1233 | .nr VS 12p |
---|
1234 | .vs 12p |
---|
1235 | .SH |
---|
1236 | Appendix: Synopsis of RCS Operations |
---|
1237 | .LP |
---|
1238 | .IP "\fIci\fP \fB\- check in revisions\fP" |
---|
1239 | .sp 0 |
---|
1240 | \fICi\fR stores the contents of a working file into the |
---|
1241 | corresponding RCS file as a new revision. |
---|
1242 | If the RCS file doesn't exist, \fIci\fR creates it. |
---|
1243 | \fICi\fR removes the working file, unless one of the options |
---|
1244 | \fI\-u\fR or \fI\-l\fR is present. |
---|
1245 | For each check-in, \fIci\fR asks for a commentary |
---|
1246 | describing the changes relative to the previous revision. |
---|
1247 | .sp 1 |
---|
1248 | \fICi\fR assigns the revision number given by the \fI\-r\fR option; |
---|
1249 | if that option is missing, it derives the number from the |
---|
1250 | lock held by the user; if there is no lock and locking is not strict, |
---|
1251 | \fIci\fR increments the number of the latest revision on the trunk. |
---|
1252 | A side branch can only be started by explicitly specifying its |
---|
1253 | number with the \fI\-r\fR option during check-in. |
---|
1254 | .sp 1 |
---|
1255 | \fICi\fR also determines |
---|
1256 | whether the revision to be checked in is different from the |
---|
1257 | previous one, and asks whether to proceed if not. |
---|
1258 | This facility simplifies check-in operations for large systems, |
---|
1259 | because one need not remember which files were changed. |
---|
1260 | .sp 1 |
---|
1261 | The option \fI\-k\fR searches the checked in file for identification |
---|
1262 | markers containing |
---|
1263 | the attributes |
---|
1264 | revision number, check-in date, author and state, and assigns these |
---|
1265 | to the new revision rather than computing them. This option is |
---|
1266 | useful for software distribution: Recipients of distributed software |
---|
1267 | using RCS should check in updates with the \fI\-k\fR option. |
---|
1268 | This convention guarantees that revision numbers, check-in dates, |
---|
1269 | etc., are the same at all sites. |
---|
1270 | .IP "\fIco\fP \fB\- check out revisions\fP" |
---|
1271 | .sp 0 |
---|
1272 | \fICo\fR retrieves revisions according to revision number, |
---|
1273 | date, author and state attributes. It either places the revision |
---|
1274 | into the working file, or prints it on the standard output. |
---|
1275 | \fICo\fR always expands the identification markers. |
---|
1276 | .IP "\fIident\fP \fB\- extract identification markers\fP" |
---|
1277 | .sp 0 |
---|
1278 | \fIIdent\fR extracts the identification markers expanded by \fIco\fR |
---|
1279 | from any file and prints them. |
---|
1280 | .IP "\fIrcs\fP \fB\- change RCS file attributes\fP" |
---|
1281 | .sp 0 |
---|
1282 | \fIRcs\fR is an administrative operation that changes access lists, |
---|
1283 | locks, unlocks, breaks locks, toggles the strict-locking feature, |
---|
1284 | sets state attributes and symbolic revision numbers, changes the |
---|
1285 | description, and deletes revisions. A revision can |
---|
1286 | only be deleted if it is not the fork of a side branch. |
---|
1287 | .br |
---|
1288 | .ne 10 |
---|
1289 | .IP "\fIrcsclean\fP \fB\- clean working directory\fP" |
---|
1290 | .sp 0 |
---|
1291 | \fIRcsclean\fR removes working files that were checked out but never changed.* |
---|
1292 | .FS * |
---|
1293 | The \fIrcsclean\fP and \fIrcsfreeze\fP commands |
---|
1294 | are optional and are not always installed. |
---|
1295 | .FE |
---|
1296 | .IP "\fIrcsdiff\fP \fB\- compare revisions\fP" |
---|
1297 | .sp 0 |
---|
1298 | \fIRcsdiff\fR compares two revisions and prints their |
---|
1299 | difference, using the UNIX tool \fIdiff\fR. |
---|
1300 | One of the revisions compared may be checked out. |
---|
1301 | This command is useful for finding out about changes. |
---|
1302 | .IP "\fIrcsfreeze\fP \fB\- freeze a configuration\fP" |
---|
1303 | .sp 0 |
---|
1304 | \fIRcsfreeze\fR assigns the same symbolic revision number |
---|
1305 | to a given revision in all RCS files. |
---|
1306 | This command is useful for accurately recording a configuration.* |
---|
1307 | .IP "\fIrcsmerge\fP \fB\- merge revisions\fP" |
---|
1308 | .sp 0 |
---|
1309 | \fIRcsmerge\fR merges two revisions, \fIrev1\fR and \fIrev2\fR, |
---|
1310 | with respect to a common ancestor. |
---|
1311 | A 3-way file comparison determines the segments of lines that |
---|
1312 | are (a) the same in all three revisions, or (b) the same in 2 revisions, |
---|
1313 | or (c) different in all three. For all segments of type (b) where |
---|
1314 | \fIrev1\fR is the differing revision, |
---|
1315 | the segment in \fIrev1\fR replaces the corresponding segment of \fIrev2\fR. |
---|
1316 | Type (c) indicates an overlapping change, is flagged as an error, and requires user |
---|
1317 | intervention to select the correct alternative. |
---|
1318 | .IP "\fIrlog\fP \fB\- read log messages\fP" |
---|
1319 | .sp 0 |
---|
1320 | \fIRlog\fR prints the log messages and other information in an RCS file. |
---|
1321 | .bp |
---|
1322 | .LP |
---|
1323 | .nr VS 12p |
---|
1324 | .vs 12p |
---|
1325 | .]< |
---|
1326 | .ds [F 1 |
---|
1327 | .]- |
---|
1328 | .ds [K FELD02 |
---|
1329 | .ds [K MakeArticle |
---|
1330 | .ds [A Feldman, Stuart I. |
---|
1331 | .ds [D March 1979 |
---|
1332 | .ds [T Make\*-A Program for Maintaining Computer Programs |
---|
1333 | .ds [J Software\*-Practice & Experience |
---|
1334 | .ds [V 9 |
---|
1335 | .ds [N 3 |
---|
1336 | .ds [P 255-265 |
---|
1337 | .nr [P 1 |
---|
1338 | .nr [T 0 |
---|
1339 | .nr [A 1 |
---|
1340 | .nr [O 0 |
---|
1341 | .][ 1 journal-article |
---|
1342 | .ds [F 2 |
---|
1343 | .]- |
---|
1344 | .ds [K HUNT01 |
---|
1345 | .ds [T An Algorithm for Differential File Comparison |
---|
1346 | .ds [A Hunt, James W. |
---|
1347 | .as [A " and McIlroy, M. D. |
---|
1348 | .ds [I Computing Science Technical Report, Bell Laboratories |
---|
1349 | .ds [R 41 |
---|
1350 | .ds [D June 1976 |
---|
1351 | .nr [T 0 |
---|
1352 | .nr [A 1 |
---|
1353 | .nr [O 0 |
---|
1354 | .][ 4 tech-report |
---|
1355 | .ds [F 3 |
---|
1356 | .]- |
---|
1357 | .ds [K SCCS |
---|
1358 | .ds [A Rochkind, Marc J. |
---|
1359 | .ds [D Dec. 1975 |
---|
1360 | .ds [T The Source Code Control System |
---|
1361 | .ds [J IEEE Transactions on Software Engineering |
---|
1362 | .ds [V SE-1 |
---|
1363 | .ds [N 4 |
---|
1364 | .ds [P 364-370 |
---|
1365 | .nr [P 1 |
---|
1366 | .nr [T 0 |
---|
1367 | .nr [A 1 |
---|
1368 | .nr [O 0 |
---|
1369 | .][ 1 journal-article |
---|
1370 | .ds [F 4 |
---|
1371 | .]- |
---|
1372 | .ds [K TICH08 |
---|
1373 | .ds [T Design, Implementation, and Evaluation of a Revision Control System |
---|
1374 | .ds [A Tichy, Walter F. |
---|
1375 | .ds [B Proceedings of the 6th International Conference on Software Engineering |
---|
1376 | .ds [I ACM, IEEE, IPS, NBS |
---|
1377 | .ds [D September 1982 |
---|
1378 | .ds [P 58-67 |
---|
1379 | .nr [P 1 |
---|
1380 | .nr [T 0 |
---|
1381 | .nr [A 1 |
---|
1382 | .nr [O 0 |
---|
1383 | .][ 3 article-in-book |
---|
1384 | .ds [F 5 |
---|
1385 | .]- |
---|
1386 | .ds [K LEBL01 |
---|
1387 | .ds [A Leblang, David B. |
---|
1388 | .as [A " and Chase, Robert P. |
---|
1389 | .ds [T Computer-Aided Software Engineering in a Distributed Workstation Environment |
---|
1390 | .ds [O Proceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium |
---|
1391 | .as [O " on Practical Software Development Environments. |
---|
1392 | .ds [J SIGPLAN Notices |
---|
1393 | .ds [V 19 |
---|
1394 | .ds [N 5 |
---|
1395 | .ds [D May 1984 |
---|
1396 | .ds [P 104-112 |
---|
1397 | .nr [P 1 |
---|
1398 | .nr [T 0 |
---|
1399 | .nr [A 1 |
---|
1400 | .nr [O 0 |
---|
1401 | .][ 1 journal-article |
---|
1402 | .ds [F 1 |
---|
1403 | .ds [F 3 |
---|
1404 | .ds [F 6 |
---|
1405 | .]- |
---|
1406 | .ds [K SCCSEval |
---|
1407 | .ds [A Glasser, Alan L. |
---|
1408 | .ds [D Nov. 1978 |
---|
1409 | .ds [T The Evolution of a Source Code Control System |
---|
1410 | .ds [J Software Engineering Notes |
---|
1411 | .ds [V 3 |
---|
1412 | .ds [N 5 |
---|
1413 | .ds [P 122-125 |
---|
1414 | .nr [P 1 |
---|
1415 | .ds [O Proceedings of the Software Quality and Assurance Workshop. |
---|
1416 | .nr [T 0 |
---|
1417 | .nr [A 1 |
---|
1418 | .nr [O 1 |
---|
1419 | .][ 1 journal-article |
---|
1420 | .ds [F 5 |
---|
1421 | .ds [F 7 |
---|
1422 | .]- |
---|
1423 | .ds [K IBMClearCaster |
---|
1424 | .ds [A Brown, H.B. |
---|
1425 | .ds [D 1970 |
---|
1426 | .ds [T The Clear/Caster System |
---|
1427 | .ds [J Nato Conference on Software Engineering, Rome |
---|
1428 | .nr [T 0 |
---|
1429 | .nr [A 1 |
---|
1430 | .nr [O 0 |
---|
1431 | .][ 1 journal-article |
---|
1432 | .ds [F 3 |
---|
1433 | .ds [F 8 |
---|
1434 | .]- |
---|
1435 | .ds [K HabermannSDC |
---|
1436 | .ds [A Habermann, A. Nico |
---|
1437 | .ds [D Jan. 1979 |
---|
1438 | .ds [T A Software Development Control System |
---|
1439 | .ds [I Technical Report, Carnegie-Mellon University, Department of Computer Science |
---|
1440 | .nr [T 0 |
---|
1441 | .nr [A 0 |
---|
1442 | .nr [O 0 |
---|
1443 | .][ 2 book |
---|
1444 | .ds [F 9 |
---|
1445 | .]- |
---|
1446 | .ds [K CMS |
---|
1447 | .ds [A DEC |
---|
1448 | .ds [T Code Management System |
---|
1449 | .ds [I Digital Equipment Corporation |
---|
1450 | .ds [O Document No.\ EA-23134-82 |
---|
1451 | .ds [D 1982 |
---|
1452 | .nr [T 0 |
---|
1453 | .nr [A 0 |
---|
1454 | .nr [O 0 |
---|
1455 | .][ 2 book |
---|
1456 | .ds [F 10 |
---|
1457 | .]- |
---|
1458 | .ds [K LAMP01 |
---|
1459 | .ds [A Lampson, Butler W. |
---|
1460 | .as [A " and Schmidt, Eric E. |
---|
1461 | .ds [T Practical Use of a Polymorphic Applicative Language |
---|
1462 | .ds [B Proceedings of the 10th Symposium on Principles of Programming Languages |
---|
1463 | .ds [I ACM |
---|
1464 | .ds [P 237-255 |
---|
1465 | .nr [P 1 |
---|
1466 | .ds [D January 1983 |
---|
1467 | .nr [T 0 |
---|
1468 | .nr [A 1 |
---|
1469 | .nr [O 0 |
---|
1470 | .][ 3 article-in-book |
---|
1471 | .ds [F 5 |
---|
1472 | .ds [F 11 |
---|
1473 | .]- |
---|
1474 | .ds [K TICH07 |
---|
1475 | .ds [T A Data Model for Programming Support Environments and its Application |
---|
1476 | .ds [A Tichy, Walter F. |
---|
1477 | .ds [B Automated Tools for Information System Design and Development |
---|
1478 | .ds [E Hans-Jochen Schneider and Anthony I. Wasserman |
---|
1479 | .ds [C Amsterdam |
---|
1480 | .ds [I North-Holland Publishing Company |
---|
1481 | .ds [D 1982 |
---|
1482 | .nr [T 0 |
---|
1483 | .nr [A 1 |
---|
1484 | .nr [O 0 |
---|
1485 | .][ 3 article-in-book |
---|
1486 | .ds [F 4 |
---|
1487 | .ds [F 2 |
---|
1488 | .ds [F 12 |
---|
1489 | .]- |
---|
1490 | .ds [K HECK01 |
---|
1491 | .ds [T A Technique for Isolating Differences Between Files |
---|
1492 | .ds [A Heckel, Paul |
---|
1493 | .ds [J Communications of the ACM |
---|
1494 | .ds [D April 1978 |
---|
1495 | .ds [V 21 |
---|
1496 | .ds [N 4 |
---|
1497 | .ds [P 264-268 |
---|
1498 | .nr [P 1 |
---|
1499 | .nr [T 0 |
---|
1500 | .nr [A 0 |
---|
1501 | .nr [O 0 |
---|
1502 | .][ 1 journal-article |
---|
1503 | .ds [F 13 |
---|
1504 | .]- |
---|
1505 | .ds [K TICH11 |
---|
1506 | .ds [T The String-to-String Correction Problem with Block Moves |
---|
1507 | .ds [A Tichy, Walter F. |
---|
1508 | .ds [D Nov. 1984 |
---|
1509 | .ds [J ACM Transactions on Computer Systems |
---|
1510 | .ds [V 2 |
---|
1511 | .ds [N 4 |
---|
1512 | .ds [P 309-321 |
---|
1513 | .nr [P 1 |
---|
1514 | .nr [T 0 |
---|
1515 | .nr [A 1 |
---|
1516 | .nr [O 0 |
---|
1517 | .][ 1 journal-article |
---|
1518 | .]> |
---|