[comp.sources.unix] v19i043: A software configuration management system, Part30/33

rsalz@uunet.uu.net (Rich Salz) (06/08/89)

Submitted-by: Axel Mahler <unido!coma!axel>
Posting-number: Volume 19, Issue 43
Archive-name: shape/part30



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 30 (of 33)."
# Contents:  papers/lisbon.ms
# Wrapped by rsalz@papaya.bbn.com on Thu Jun  1 19:27:19 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'papers/lisbon.ms' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'papers/lisbon.ms'\"
else
echo shar: Extracting \"'papers/lisbon.ms'\" \(46807 characters\)
sed "s/^X//" >'papers/lisbon.ms' <<'END_OF_FILE'
X.IZ
X.sp -0.9di
X.ND
X.nr UX 1
X\" --- cut here --- 
X.AM
X.ds Rf References
X.ds Un \\s-1\\f(HBU\\s-2NI\\s+2B\\s-2ASE\\fR\\s+3
X.ds Co \\s-2\\f(HBCOMA\\fR\\s+2
X.ds Da \\s-2\\f(HBDAMOKLES\\fR\\s+2
X.ds Th \\s-2\\f(HBTHESEUS\\fR\\s+2
X.ds Mk Make
X.ds sh \\s-1\\f(HBshape\\fR\\s+1
X.ds Af AFS
X.TL
XAn Object Base for Attributed Software Objects\(dg
X.FS
X\(dg in \fIProceedings of the EUUG Autumn '88 Conference\fR
X.br
X(Cascais, 3-7 October 1988), pp. 95-105, European UNIX Users Group, London 1988
X.FE
X.AU
XAndreas Lampen, Axel Mahler
Xandy@coma.uucp, axel@coma.uucp
X.AI
XTechnische Universit\*:at Berlin
XSekretariat FR 5-6
XFranklinstr. 28/29
XD-1000 Berlin 10
X.AB
XThe
X.UX
Xfilesystem supports a fixed set of attributes for filesystem
Xobjects, stored in inodes and directory entries.
XThe (path-)name attribute is the sole means to identify
Xand access a filesystem object.
XThis turns out to be a rather severe limitation for certain
Xcomplex applications such as large scale software development,
Xwhere software objects typically evolve in a considerable number of
Xversions.
X.LP
XAn approach to improve the situation
Xis introduced by the \fIattribute filesystem\fR (\*(Af),
Xthe system described in this paper.
XThe \*(Af combines the notion of immutable objects (versions)
Xwith the possibility to attach any number of user-definable
Xattributes to any attributed software object (ASO).
X\*(Af objects can be identified by specifying any set of
Xattribute value(s) as retrieve pattern.
XThe \fIname\fR of an \*(Af object is treated as \fIjust another attribute\fR.
XThe \*(Af is equipped with a proper retrieve interface that allows
Xnon-unique identification of \fIsets of objects\fR and provides
Xoperations on those sets.
X.LP
XThe \*(Af is a significant extension to the
X.UX
Xfilesystem interface providing applications with a unified,
Xconsistent view of attributed filesystem objects comprising
Ximmutable versions and ordinary
X.UX
Xfiles.
XThe concept of \fIpersistent objects\fR makes \*(Af a basis
Xfor object oriented applications in an
X.UX
Xenvironment. 
XWe used \*(Af as a basis for the implementation of the \*(sh toolkit,
Xa collection of programs supporting
Xsoftware configuration management in multi-programmer software
Xdevelopment projects.
X.LP
XOne important objective of \*(Af is to abstract from the actually
Xunderlying data storage system. This paper will briefly discuss
Xtwo different implementations of \*(Af \- one on top of the
X.UX
Xfilesystem and the other based on \*(Da, a dedicated software
Xengineering database.
X.AE
X.NH 1
XIntroduction
X.LP
XThe context of this work was the design of a software configuration
Xmanagement system to be part of a kernel of an open
X.UX
Xbased software engineering environment.
XLarge scale software development requires a system
Xcapable to store a big number of software objects, typically
Xevolving in a considerable number of versions.
X.LP
XThe
X.UX
Xfilesystem is a good basis for this job but it has
Xsome severe limitations.
XIt supports only a fixed set of attributes for filesystem
Xobjects, stored in inodes and directory entries.
XThe (path-)name attribute is the sole means to identify
Xand access a filesystem object.
XVersion control systems had to be introduced as auxiliary tools,
Xto avoid name clashes and to store multiple versions
Xof files in an space efficient manner.
XHowever, they do not overcome the fundamental shortcomings
Xof the
X.UX
Xfilesystem.
XThey represent partial solutions to particular problems
Xand integrate poorly with
X.UX
Xtools such as \*(Mk [2].
X.LP
XAs a try to overcome these limitations we designed the \fIattribute
Xfilesystem\fR (\*(Af), the system described in this paper.
XWe use the name attribute \fIfilesystem\fR mainly for historical
Xreasons (because we are used to it and we haven't found a better
Xname yet).
XSo don't be confused when we subsequently refer to
X\*(Af as an \fIobject base\fR rather than a filesystem.
XAccordingly we will use the term \fIsoftware object\fR instead of
X\fIfile\fR throughout this paper.
X.LP
XAn object base is a hybrid of filesystem and database trying
Xto combine the advantages of both types of data storage systems.
XThe advantages of an object base over a filesystem
Xlie in its
X.IP \(bu 0.2i
Xmore general object identification scheme,
X.IP \(bu
Xability to store multiple versions of objects,
X.IP \(bu
Xsupport for the management of arbitrary attributes for objects and
X.IP \(bu
Xabstraction from the physical representation of objects.
X.RE
X.LP
XImprovements in respect to database systems are
X.IP \(bu 0.2i
Xthe concept \fIobject\fR
Xas manageable, user identifyable, interchangeable piece of data
Xand a common understanding of how data looks like (a basis for integration
Xof existing and new tools),
X.IP \(bu
Xno need for a schema (i.e. no problems with schema updates),
X.IP \(bu
Xbetter network support (\fIobjects\fR are quite easyly interchangeable
Xbetween different machines) and
X.IP \(bu
Xbetter performance (in most cases)
X.RE
X.LP
XFor a detailed discussion on how a persistent object base should
Xlook like, see [6].
X.LP
X\*(Af is designed as basis for the \*(sh-toolkit, described in  [4]
Xand [5].
XThe \*(sh-toolkit is a configuration management toolkit
Xintegrating a dedicated version control system and \*(sh, a
Xsignificantly enhanced \*(Mk program.
XEnhancements include full access to the version control system.
X\*(sh's procedure of identifying
Xappropriate component versions that together form a meaningful system 
Xconfiguration may be completely controlled by user-supplied \fIconfiguration
Xselection rules\fR. Selection rules are placed in the \fIShapefile\fR,
X\*(sh's counterpart to the Makefile.
X.LP
XThe next chapter gives an overview of the basic concepts of \*(Af.
XIn chapter 3, we briefly describe the interface and have a
Xlook at two different implementations.
XThe last chapter contains an outlook on current development
Xefforts to make \*(Af a basis for object oriented applications.
X.NH 1
XGeneral design
X.LP
X\*(Af is a system to store software objects as 
Xa complex of (from the AFS' point of view) unstructured
Xcontent data and an arbitrary
Xnumber of associated attributes.
XWe call these objects \fIattributed software objects\fR (ASOs).
X\*(Af has a built-in version control system that supports the storage
Xand identification of different versions of \fIdesign objects\fR.
XA design object consists of a group of
Xsuccessive versions evolving by taking snapshots of the current
Xdevelopment state from time to time.
XThroughout this paper we also use the term \fIline of development\fR
Xsynonymously to \fIdesign object\fR.
XEach version of a design object is an attributed software object on its own.
XFor a more detailed discussion of software engineering terms see [10].
X.LP
XDue to the requirements of a multi programmer software
Xdevelopment environment we introduced
Xa mechanism for reserving update rights for design objects
Xby setting a lock on this object.
XReserving the update right has
Xthe effect, that updates can only be stored by the user
Xcurrently holding the lock.
X.LP
X\*(Af was designed to be a basis for integration of a large spectrum
Xof different software development tools.
XThese may be editors, compilers, formatters,
Xa software configuration management system, tools for
Xproject planning and status accounting, test support, specification
Xand design tools \(em a potentially very long list.
XIn respect to tool integration, an
Xengineering environment has to offer some form of
Xintelligent support for the user in order to improve
Xthe situation presented by mere toolbox systems.
XHowever, it is not feasible for the object
Xmanagement part of such an environment to understand the
Xformal semantics contained \fIin\fR the various types of
Xobjects it manages.
XThe functional behavior of an environment's object manager
Xshould rather be guided by simple information \fIabout\fR the
Xmanaged objects.
XAttributes enable each \*(Af application program to store information
Xabout a software object persistently either for later use or
Xleaving them for interpretation by other \*(Af applications (or both).
X.LP
XIt is likely that the number of needed attributes will grow with each new
Xtool using \*(Af.
XAs we cannot foresee which new \*(Af applications will be
Xintroduced in the future, we are not able to define a fixed set of
Xattributes serving all needs.
XInstead, we decided to keep the number of attributes
Xfor each stored object dynamically extensible.
XBesides some standard attributes (such as name, size or version), 
Xeach software object is stored with a potentially infinite number of
Xapplication-defined attributes.
X.LP
XAnother important design goal was the introduction of a
Xconcept for the integration of standard
X.UX
Xtools and off\-the\-shelf tools that operate on regular files.
XFor this purpose, \*(Af is designed to be able to coexist with the
X.UX
Xfilesystem.
XIt allows regular
X.UX
Xfiles to be treated as \*(Af objects and to be accessed through the \*(Af
Xinterface.
XThis opens a way to exchange data between existing tools that operate on
X.UX
Xfiles and tools on top of \*(Af (such as the \*(sh toolkit).
XFigure 2.1 illustrates the tool integration on base
Xof \*(Af. \*(Af is a C\-language interface that abstracts from the
Xunderlying data storage system (e.g. a filesystem or a database).
X.KF
X.sp 5p
X.PS
X    boxht=0.6i
X    move right 0.9i
XDs: box wid 2.2i "Data Storage System" "(e.g. Filesystem or Database)"
X    box wid 1.9i "UNIX filesystem"
X    move to Ds.nw; move up 0.3i; move right 0.2i;
XAf: box wid 2.6i "Attribute File System"; move up 0.3i; right
X    box ht 1.2i wid 1i "other" "programs:" "Editors" "Compilers" "Formatters"
X    move to Af.nw; move up 0.3i; move right 0.2i
X    box wid 0.8i "Version" "Control" "Commands"
X    box wid 0.8i "\*(sh"
X    box wid 0.8i "other" "AFS" "Applications"
X.PE
X.sp 5p
X.ce
X\fBFig. 2.1:\fR The AFS and its applications
X.sp 5p
X.KE
X.LP
XApart from versions and attributes, \*(Af looks very much like the
X.UX
Xfilesystem with a hierarchical directory structure, special files and so on.
X.LP
X.NH 2
XSource objects and derived objects
X.LP
X\*(Af manages \fIlines of development\fR. A line of development
Xconsists of a \fIbusy object\fR and a number of saved versions.
XThe busy object is an ordinary alterable
X.UX
Xfile.
XIt can be accessed via \*(Af \fIand\fR
X.UX
Xfilesytem operations.
XVersions come into being by making a copy of the current state of
Xthe busy object.
XThey can be stored as source objects or as derived objects.
X.LP
XSource objects are typically composed manually (e.g. by use of a
Xtext editor).
X\*(Af stores source objects as immutable objects.
XOnce saved, they cannot be modified any longer.
XThey can only be explicitly removed by their owner or author.
XSource objects can be uniquely identified by the attribute values
Xfor \fIhostname, system path, name, type, generation number,
Xrevision number\fR and \fIvariant\fR.
X.LP
XDerived objects are typically derived automatically (e.g. by a
Xcompiler) from a source object and thus be reproducible at any time.
XThey are kept in a \fIderived object pool\fR ( see also [3]
X), a data store of limited
Xsize that is administered in a cache fashion. The oldest (access
Xdate) derived objects get removed if space runs short in the binary
Xpool. Unlike source objects, the tupel (\fIhostname, system path, name,
Xtype, generation number, revision number, variant\fR) does not necessarily
Xhave to be unique for derived objects. Derived
Xobjects may differ only in user defined attributes !
X.LP
X\*(Af makes no assumptions whether a copy of a busy object shall be
Xstored as source object or as derived object.
XThis has to be decided by the application.
X.NH 2
XAttributed Software Objects
X.LP
XAttributes have the general form \fIname=[value [value ...]]\fR.
XFigure 2.2 illustrates the term attributed software object.
X.KF
X.PS
X    move right 1.1i
XDa: box ht 2i wid 1.5i "\s+9\f(HBDATA\fR\s-9"
X    line from Da.nw - 0,0.1 to Da.nw + 0.1,0
X    line from Da.nw - 0,0.2 to Da.nw + 0.2,0
X    line from Da.nw - 0,0.3 to Da.nw + 0.3,0
X    line from Da.nw - 0,0.4 to Da.nw + 0.4,0
X    line from Da.nw - 0,0.5 to Da.nw + 0.5,0
X    line from Da.nw - 0,0.6 to Da.nw + 0.6,0
X    line from Da.nw - 0,0.7 to Da.nw + 0.7,0
X    line from Da.nw - 0,0.8 to Da.nw + 0.8,0
X    line from Da.nw - 0,0.9 to Da.nw + 0.9,0
X    line from Da.nw - 0,1.0 to Da.nw + 1.0,0
X    line from Da.nw - 0,1.1 to Da.nw + 1.1,0
X    line from Da.nw - 0,1.2 to Da.nw + 1.2,0
X    line from Da.nw - 0,1.3 to Da.nw + 1.3,0
X    line from Da.nw - 0,1.4 to Da.nw + 1.4,0
X    line from Da.nw - 0,1.5 to Da.nw + 1.5,0
X    line from Da.nw - 0,1.6 to Da.ne - 0,0.1
X    line from Da.nw - 0,1.7 to Da.ne - 0,0.2
X    line from Da.nw - 0,1.8 to Da.ne - 0,0.3
X    line from Da.nw - 0,1.9 to Da.ne - 0,0.4
X    line from Da.nw - 0,2.0 to Da.ne - 0,0.5
X    line from Da.sw + 0.1,0 to Da.ne - 0,0.6
X    line from Da.sw + 0.2,0 to Da.ne - 0,0.7
X    line from Da.sw + 0.3,0 to Da.ne - 0,0.8
X    line from Da.sw + 0.4,0 to Da.ne - 0,0.9
X    line from Da.sw + 0.5,0 to Da.ne - 0,1.0
X    line from Da.sw + 0.6,0 to Da.ne - 0,1.1
X    line from Da.sw + 0.7,0 to Da.ne - 0,1.2
X    line from Da.sw + 0.8,0 to Da.ne - 0,1.3
X    line from Da.sw + 0.9,0 to Da.ne - 0,1.4
X    line from Da.sw + 1.0,0 to Da.ne - 0,1.5
X    line from Da.sw + 1.1,0 to Da.ne - 0,1.6
X    line from Da.sw + 1.2,0 to Da.ne - 0,1.7
X    line from Da.sw + 1.3,0 to Da.ne - 0,1.8
X    line from Da.sw + 1.4,0 to Da.ne - 0,1.9
X    move to Da.se + 0.5,0
XAt: line up 2.1i; line right 1.5i; line down 2i
X    move left 1.45i; line right 1.5i; down
X    arc from Here - 0,0.2i to Here rad 0.1i; move down 0.2i
X    line left 1.5i; up; ellipsewid = 0.1i; ellipseht = 0.2i; ellipse
X    move to Da.ne + 0.6i,0; move down 0.1i
X    "name=otto" ljust; move down 0.12i
X    "type=c" ljust; move down 0.12i
X    "generation=4" ljust; move down 0.12i
X    "revision=3" ljust; move down 0.12i
X    "variant=" ljust; move down 0.12i
X    "state=saved" ljust; move down 0.12i
X    "author=andy" ljust; move down 0.12i
X    "mode=0644" ljust; move down 0.12i
X    "mdate=881001-12:22:34" ljust; move down 0.12i
X    "sdate=881002-22:44:16" ljust; move down 0.12i
X    "project=shape" ljust; move down 0.12i
X    "testlevel=low" ljust; move down 0.12i
X    "do_next=fix retrv-bug" ljust; move down 0.12i
X    "..." ljust
X
X    line from Da.ne - 0,0.9 right 0.5i up 0.1i
X    line from Da.ne - 0,1.1 right 0.5i up 0.1i
X.PE
X.sp 5p
X.ce
X\fBFig. 2.2:\fR An Attributed software object
X.sp 5p
X.KE
X.LP
X\*(Af supports a set of standard attributes for each ASO.
XThese are
X.IP \(bu 0.2i
Xhostname, system path, name, type,
X.IP \(bu
Xgeneration number, revision number, variant name, version state,
X.IP \(bu
Xowner, author,
X.IP \(bu
Xsize,
X.IP \(bu
Xaccess permissions, lock,
X.IP \(bu
Xdate of last modification, \- last access, \- last status change,
X\- saving and \- last lock change
X.RE
X.LP
XThe \fIsystem path\fR attribute is used to describe the (logical)
Xposition of an ASO in a complex, hierarchically structured
Xsystem. \fISystem path, name\fR and
X\fItype\fR are currently mapped to
X.UX
Xpathnames where they take the place of path prefix, filename (without suffix)
Xand filename suffix. For example: the system path \fC/usr/axel\fR,
Xname \fCfoo\fR and type \fCc\fR are mapped to the
X.UX
Xfilename \fC/usr/axel/foo.c\fR.
XAdditionally to the \fIowner\fR attribute known from
X.UX
Xfiles ASOs also have an \fIauthor\fR attribute.
X\*(Af distinguishes the \fIowner\fR of an entire design object
Xand the \fIauthor\fR of a particular version. 
X.LP
XIn addition to the standard attributes, an application may attach any
Xnumber of \fIuser defined attributes\fR to any ASO.
XInterpretation and use of these attributes is left to the application
Xthat uses them.
X\*(Af manages user defined attributes as a structure containing
Xthe attribute name and a (possibly empty) set of strings
Xholding the associated attribute value(s).
X.LP
XAttributes can be used for very different purposes.
XThe standard attributes are used mainly for ordering and 
Xidentifying software objects and for general management.
XUser defined attributes will be used to store application
Xspecific information with an ASO.
X.LP
XA typical example for the use of user defined attributes
Xcan be found in the \*(sh program.
XFor each derived object (e.g. an object file that is produced by
Xcompiling a C source file), the name of the transformation tool
Xand all given flags and parameters are protocoled in an
Xattribute.
XBesides the description of the transformation process, the name(s)
Xand version(s) of the involved source
Xobject(s) are recorded as list of values in another attribute.
XThis enables \*(sh to handle recompilations in a much more
Xsophisticated way than Make.
X.LP
XAnother example might be a tiny program that allows a user
Xto associate any number of keywords with his software objects.
XSuch a program would allow a grouping of ASOs via keywords
Xindependently of the directory structure.
XUser defined attributes can also be used to model references
Xbetween ASOs.
XAttaching the identification of the corresponding source object
Xas attribute to a derived object actually \fIis\fR a reference.
X.LP
XThe full power of the concept of user defined attributes is hardly 
Xused yet but we feel that there \fIis\fR a lot of power in this approach.
XOur first application programs use this mechanism in a
Xstraightforward manner (illustrated in the examples above) and it works fine.
XUser defined attributes may also be used in a more exotic way
Xsuch as to store patches (e.g. ed scripts generated by \fIdiff\fR)
Xto source objects.
X.LP
XOn the basis of user defined attributes it will further be quite
Xeasy to construct a general object class manager that
Xprovides an interface for the storage of typed software
Xobjects with type specific attributes.
XThis will be discussed in greater detail in chapter 4.
X.NH 2
XIdentification and Object-Keys
X.LP
XDue to the introduction of versions, ASOs cannot be uniquely
Xidentified by just giving their (path-)name (like in the
X.UX
Xfilesystem).
XFor the identification of attributed software objects, all attributes
Xare considered equally qualified.
X\*(Af is equipped
Xwith a retrieve interface for nonunique identification of sets of ASOs.
XA retrieve operation is driven by an attribute pattern containing
Xall desired attribute values.
X.LP
XOnce identified, an ASO is represented by a unique \fIObject-key\fR
Xby which it can be accessed further on.
XObject keys can be fetched from a set, delivered by a retrieve
Xoperation.
XSelecting an object key from a set is supported by operations
Xfor sorting sets by attribute values, recursive retrieve (a retrieve
Xoperation with a set as search space) and building unions,
Xintersections, or differences between two sets.
X.KF
X.sp 5p
X.PS
X    boxwid = 0.6i; boxht = 0.6i; circlerad = 0.3i;
X    circle "set of" "required" "attrs."; arrow right 0.15i
X    box "AFS" "retrieve"; arrow right 0.15i
X    circle "set of" "object" "keys"; arrow right 0.15i
X    box "SELECT" "OBJECT" "KEY"; arrow right 0.15i
XSo: circle "single" "object key"
XGa: box "AFS" "get" "attributes" at So + 0.7i,0.4i
XAo: box "AFS" "open" at So + 0.7i,-0.4i; arrow right 0.15i
X    circle "FILE" "descriptor"; arrow right 0.15i
X    box "file-" "system" "I/O"
X    arrow from So to Ao chop 
X    arrow from So to Ga chop
X.PE
X.sp 5p
X.ce
X\fBFig. 2.3:\fR Access principle for ASOs
X.sp 5p
X.KE
X.LP
XAccess to the attributes as well as the contents on an ASO is also
Xestablished via object keys.
XTo access its contents, an ASO has to be opened.
XOnce opened, the content data of an ASO can be read and written
Xas regular
X.UX
Xfiles (see fig. 2.3).
X.NH 2
XVersion Control
X.LP
X\*(Af maintains a sequence of \fIrevisions\fR (successive versions)
Xfor each design object.
XThe numbering of revisions in a line of development is under control of
Xthe \*(Af. Every time when a new revision is generated by saving
Xa copy of the busy object, it is assigned a version identification of the form
X\fIgeneration.revision\fR (e.g. 1.0 or 4.3).
XGeneration numbers indicate major development steps that
Xare common to all components of a complex system.
XThe revision number serves as an update sequence number for individual
Xcomponents within a generation.
X.LP
XBesides revisions, a version control system has to be able to store
X\fIvariants\fR \- qualitatively equivalent versions differing in a
Xcertain property \- of source objects.
XA typical example for variants is a user interface module
Xthat deals with different window systems.
XUnlike the identification of revisions, where a generation.revision
Xnumbering scheme turned out to be common sense, there is no
Xusual variant naming scheme.
XWe know systems, where variants are numbered, named (with single
Xor multiple names) or both.
X.LP
XThe general management of variants is a major conceptual problem.
XThe idea of variants sounds quite simple, but
Xto actually handle them can be an extremely difficult task.
XUp till now there doesn't seem to be a tool that conducts
Xthe development of system variants in a really satisfying manner.
XNevertheless we want to establish a reasonable basis for
Xsuch a tool by providing an instructive and flexible
Xvariant identification mechanism.
X\*(Af supports a \fIvariant\fR attribute (a string) for each ASO.
XThe variant attribute is totally independent from the revision
Xnumbering, i.e. each variant is stored in its own line of development
Xwith independent revision numbering.
XAny structure of the variant string (e.g. multiple variant names)
Xhas to be maintained by the application(s) [5].
X.NH 3
XBranches
X.LP
XOne major difference between the \*(Af builtin version control system
Xand classical systems like RCS [9]
Xand SCCS [8] 
Xis, that \*(Af establishes a user oriented view of versions
Xthat abstracts from the physical derivation graph.
XIn contrary to RCS and SCCS,
Xversion histories in \*(Af are essentially linear.
XLogically, new versions are always appended to the end of the
Xversion history.
XUpdates of older versions can be attached as leaves (not branches)
Xto the line of development (see fig 2.5).
XVariants are stored in parallel lines of development.
X.LP
XAt first glance, it looks like a loss of functionality of the \*(Af
Xversion control system
Xcompared to systems like RCS or SCCS (where are the branches).
XA closer look shows, that there is only a different identification
Xscheme.
X.LP
XFigures 2.4 and 2.5.
Xshow the same number of revisions/variants developed in the same way.
XThe first figure shows a RCS version tree and the second
Xshows its \*(Af pendant.
X.KF
X.sp 5p
X.PS
X    circlerad = 0.25i;
X    box ht 3.1i wid 5.8i; move to 0.3i,0;
XC1: circle "1.1"; arrow right 0.5i
XC2: circle "1.2"; arrow right 0.5i
XC3: circle "1.3"; arrow right 0.5i
XC4: circle "2.1"; arrow right 0.5i
XC5: circle "2.2"
XC6: circle "1.1.1.1" at C1 + 0.5i,0.6i; arrow from C1 to C6 chop
XC7: circle "1.2.1.1" at C2 + 0.5i,0.6i; arrow from C2 to C7 chop
XC8: circle "1.3.1.1" at C3 + 0.5i,0.6i; arrow from C3 to C8 chop
XC9: circle "1.2.3.1" at C2 + 0.5i,-0.6i; arrow from C2 to C9 chop
X    move to right of C9; arrow right 0.4i;
XC0: circle "1.2.3.2"; arrow right 0.4i; circle "1.2.3.3"
XCa: circle "1.2.2.1" at C2 + 0.3i,1.2i; arrow from C2 to Ca chop
X    move to right of Ca; arrow right 1.8i; circle "1.2.2.2"
XCb: circle "1.2.3." "2.1.1" at C0 + 0.4i,-0.6i; arrow from C0 to Cb chop
X.PE
X.sp 5p
X.ce
X\fBFig. 2.4:\fR RCS version tree
X.sp 5p
X.KE
X.KF
X.sp 5p
X.PS
X    circlerad = 0.25i;
X    move to 0,0.3i; box ht 1.3i wid 5.9i
X    move to 0,1.4i; box ht 0.7i wid 5.9i
X    move to 0,-1.1i; box ht 1.3i wid 5.9i; move to 0.3i,0;
XC1: circle "1.0"; arrow right 0.5i
XC2: circle "1.1"; arrow right 0.5i
XC3: circle "1.2 / 2.0"; arrow right 0.5i
XC4: circle "2.1"; arrow right 0.5i
XC5: circle "2.2"
XC6: circle "1.0" "fix1" at C1 + 0.5i,0.6i; arrow from C1 to C6 chop
XC7: circle "1.1" "patch1" at C2 + 0.5i,0.6i; arrow from C2 to C7 chop
XC8: circle "1.2" "fix1" at C3 + 0.5i,0.6i; arrow from C3 to C8 chop
X    circle "1.0" "X" at C2 + 0.3i,1.4i; arrow right 1.8i; circle "1.2" "X"
XC9: circle "1.1" "NeWS" at C2 + 0.5i,-1.4i; arrow right 0.4i;
XC0: circle "1.2 / 2.0" "NeWS"; arrow right 0.4i; circle "2.1" "NeWS"
XCb: circle "1.2" "NeWS" "fix1" at C0 + 0.5i,0.6i; arrow from C0 to Cb chop
X.PE
X.sp 5p
X.ce
X\fBFig. 2.5:\fR AFS lines of development
X.sp 5p
X.KE
X.LP
XThe version identification scheme of \*(Af abstracts from the
Xphysical evolution of the single versions
X(nevertheless, the physical links are there and maintained in
Xa way similar to RCS).
XRCS and SCCS present a data structure oriented view
Xof version histories to the user.
XSome nasty problems arise from mixing
Xlogical and physical derivation graph in respect to numbering/naming
Xof revisions.
XFirst, version numbers in branches get very complex (four or more numbers)
Xwhich is not very instructive. Second, although there are \(lqso many
Xnumbers\(rq there is no generation number in branches !
X.LP
XConceptually, \*(Af does not support arbitrary branching.
XBranching off the main line of development happens most of the time 
Xbecause a developer wants to
X.IP \(bu 0.2i
Xcreate a variant or
X.IP \(bu
Xstore modifications of older versions (bug-fixes or customizations) or
X.IP \(bu
Xmake experimental changes that should not necessarily
Xgo into the main line of development.
X.RE
X.LP
XThe first case should be realized by parallel lines of development.
XThe latter two cases are not explicitly supported by
X\*(Af itself.
XA solution has to be given by an application program
Xeither based on an extended use of
Xthe \fIvariant\fR attribute or on storing patches in
Xuser defined attributes.
X.NH 3
XThe version status model
X.LP
XAs a consequence of the original design of \*(Af as part of a
Xsoftware development environment,
X\*(Af provides a status model for saved source objects to support the
Ximplementation of a general project organization scheme.
XThe project organization scheme we have in mind
Xdistinguishes between private workspaces for each participating
Xprogrammer, and a central project database, where all the serious
Xresults of the programmers' efforts are collected.
X.LP
XThe basic status model that is built into the version control system
Xrecognizes the following states:
X.IP \fBbusy\fR 0.8i 
XThe object is under development and its contents may
Xbe changed.
X.IP \fBsaved\fR 
XThe object is saved and may be used for later backup.
X.IP \fBproposed\fR
XThe object has been submitted for publication by the developer
Xbut still needs formal approval by a quality assurance board
Xto become publically visible and accessible in the official
Xdatabase.
X.IP \fBpublished\fR
XThe object has passed the formal approval and is now accessible to
Xevery member of the project. It is not yet accessed and may therefore
Xbe withdrawn if necessary.
X.IP \fBaccessed\fR 
XThe object has been published, and is now 
Xaccessed by some members of the project.
X.IP \fBfrozen\fR
XThe object may be part of a system configuration
Xthat has been released to the outside world. This means it must under
Xno circumstances be destroyed.
X.RE
X.NH 1
XRealization
X.LP
XCurrently, we have two different implementations of \*(Af (in 
Xdifferent development stages).
XOne on top of the
X.UX
Xfilesytem and another one on top of \*(Da,
Xa dedicated software engineering database [1].
XBoth are written in C and provide a library interface.
XFurther developments will be made in C++ and we will implement
Xa new interface in C++.
X.LP
XThe interface of both implementations is nearly identical.
XDifferences exist only in marginal routines concerning the data
Xmanagement. For example has the \*(Da implementation additional
Xroutines for opening and closing the database.
X.NH 2
XThe Interface
X.LP
XThe main datatypes of \*(Af are:
X.IP \(bu 0.2i
XThe \fIobject key\fR that uniquely identifies a software object.
XThe structure of this type is different in the two different
Ximplementations. Consequently, application programs should handle
Xthis type as opaque type and should not access single fields
X(unfortunately this is a little bit clumsy in C \- an implementation
Xas C++ class would be more appropriate).
X.IP \(bu
X\fISet descriptors\fR represent a set of object keys.
XA set descriptor contains information about the number of keys
Xin the set and a pointer to a list of object keys.
X.IP \(bu
XAn \fIAttribute buffer\fR which is capable to hold all attributes of a
Xsoftware object (standard attributes and user defined attributes).
XAttribute buffers have two different purposes.
XFirst, they can hold a retrieve pattern, i.e. they
Xmay be (partially) filled with \fIdesired\fR attribute
Xvalues and then be passed as argument to a retrieve operation.
XSecond, an attribute buffer is used to return all attributes of
Xan identified ASO on demand.
X.RE
X.LP
XThe names of all operations of the \*(Af are preceded by \fIaf_\fR
X(e.g. \fIaf_saverev\fR).
XIn the following sections, the most important (most interesting)
Xfunctions of \*(Af are described.
X.NH 3
XRetrieval
X.LP
X\*(Af provides two different retrieval operations, \fIaf_find\fR and
X\fIaf_bpfind\fR. The first does retrieval of source objects and
Xthe second of derived objects.
XBoth have to be parameterized with an attribute buffer containing
Xa retrieve pattern and both return a set holding the keys of all
XASOs matching the specified attribute pattern.
X.LP
XDue to the possibility to uniquely identify source objects by the
Xattributes \fIhostname, syspath, name, type, generation, revision\fR
Xand \fIvariant\fR, there is a shortcut (faster) operation to get the
Xkey of well known object by specifying values for these seven
Xattributes. The name of the function is \fIaf_getkey\fR and it returns
Xan object key if the sought software object exists.
X.NH 3
XSets
X.LP
X\*(Af contains a considerable number of operations on sets.
XAlthough a set contains \fIobject keys\fR and not complete
Xobjects, we speak of \(lqobjects in a set\(rq throughout this
Xchapter for reasons of simplicity.
X.LP
X\fIAf_sortset\fR sorts the objects in a set in respect to the
Xvalue of a single or compound attribute.
XFor example, objects can be ordered alphabetically by their
Xname attribute which is a single attribute.
XA typical compound attribute is the \fIversion number\fR
Xconsisting of generation number and revision number
X(generation.revision).
XBesides standard attributes one can pass any name of a user defined
Xattribute as argument to \fIaf_sortset\fR.
XThis works, even if the attribute is not defined for every
Xobject in the set.
X.LP
XThe call \fIaf_subset\fR performs a recursive retrieve operation on
Xan existing set. \fIAf_subset\fR is (like \fIaf_find\fR)
Xparameterized with an attribute buffer containing a retrieve pattern.
XIt results in a subset of the original set.
X.LP
XOther set commands provide
Xadding and deleting single objects to/from sets as well as
Xbuilding intersections, unions and differences of two existing sets.
X.NH 3
XReading and Manipulating Attributes
X.LP
XThe manipulation of standard attributes for software objects
Xis under strict control of \*(Af.
XMany standard attributes can only be modified implicitly
Xby performing a \*(Af operation.
XThe other standard attributes can only be manipulated in
Xa well defined manner.
X.LP
XThe attributes \fIhostname, system path, name\fR and \fItype\fR
Xare immutable for saved objects (source or derived).
XThey are set once (at saving time) as inherited from the filesystem 
Xlocation of the file the object evolved from.
XAs busy objects are regular
X.UX
Xfiles, they can be renamed by linking them to another place in
Xthe filesystem.
X.LP
XVersion number and the version state are only relevant
Xfor source objects. 
XA source object is automatically assigned a version number and state
X\fIsaved\fR when it is
Xgenerated. The version number can subsequently only be increased
X(set to a logically bigger number, e.g. from 1.2 to 1.4 or from
X2.3 to 3.0).
XThe version state can be set to the logically following or
Xpreceding (see states list in 2.4) state but it can never be
Xreset to \fIbusy\fR. 
XBusy objects have no version number
Xand are always in state \fIbusy\fR.
XVersion number and state
Xof derived objects can be set arbitrarily (but \*(Af does not
Xcare about their values).
X.LP
XThe management of user defined attributes is entirely controlled by
Xthe application program.
XAn application program called by the owner
Xor the author of an ASO can arbitrarily add, delete and modify
Xthese attributes.
X\*(Af supports the management of user defined attributes
Xby storing them as name/value(s) pairs.
XA name (string) is associated with any number (zero to infinite)
Xof values (strings).
XThe function \fIaf_sudattr\fR allows the addition and deletion
Xof whole attribute entries and single values.
X.NH 3
XLocking
X.LP
XThe locking mechanism for reserving update rights in a line
Xof development is reflected by the functions \fIaf_lock, af_unlock\fR
Xand \fIaf_testlock\fR.
XCalling the function \fIaf_lock\fR, causes the identified ASO
Xto be locked by the caller, provided the object was available
Xfor locking.
X.LP
X\fIAf_testlock\fR returns the user ID of the lock holder (if present). 
XLocks can either be released by the lock holder of the design
Xobject or be broken by the owner by means of \fIaf_unlock\fR.
X.NH 3
XVersion Control
X.LP
XThe version control system has been described in detail earlier in this paper.
XThe most important operations are \fIaf_saverev\fR and \fIaf_savebinary\fR
Xwhich create a copy of the given, busy, ASO and store it as
Xnew source resp. derived version.
X.LP
X\fIAf_newgen\fR increases the generation number in a line of development.
XIt creates a pseudo revision which is identical to the last saved revision
Xand attaches a new version number to it.
XThe generated pseudo revision has the character of an alias (see also
Xfigure 2.5).
XThe new version number is generated by increasing the generation number by 1
Xand resetting the revision number to 0 (e.g. 1.4 becomes 2.0).
X.LP
XIf the busy object of a line of development was replaced by another file,
Xfor example an older version or a variant,
X\fIaf_setbusy\fR should be called with the key of the
Xold busy object and that of the new one, to inform \*(Af about the change.
XThis is necessary to keep track of the physical derivation structure of
Xa line of development which is substantially for an efficient delta
Xtechnique.
X.NH 3
XFilesystem Primitives
X.LP
X\fIAf_open\fR and \fIaf_close\fR are
Xfilesystem primitives analogous to the
X.UX
Xcalls \fIfopen\fR and \fIfclose\fR.
XThe only difference is, that \fIaf_open\fR takes an object key instead
Xof a pathname as input parameter.
X\fIAf_open\fR returns a pointer to a \fIFILE\fR structure, so that
Xthe application program can use the whole
X.UX
Xstdio interface on ASOs.
X.LP
XAdditionally, ASOs can be created and removed (unlinked).
XDerived files residing in a binary pool can be restored
Xat their former position with \fIaf_restore\fR.
X.LP
XThe interface is completed by a number of miscellaneous
Xroutines.
XThese are routines for error reporting and cleaning up
X(removing tmp files and freeing memory) as well as functions
Xfor splitting up
X.UX
Xpathnames in the \*(Af attributes syspath, name and type.
X.NH 2
X\*(Af on top of the
X.UX
Xfilesystem
X.LP
XThe first implementation of \*(Af was done on top of the
X.UX
Xfilesystem.
XThis implementation is ready and in use.
X.LP
XSaved ASOs are stored in archive files (like SCCS and RCS). \*(Af
Xmaintains two archive files for each line of development of source
Xobjects \- one holding the attributes and the other holding the data.
X\*(Af stores its archives in a subdirectory called \*(Af. If the
Xarchives shall be stored elsewhere but not in a subdirectory, an \*(Af
Xapplication can set an \fIarchive path\fR to specify the name of a
Xdirectory where all subsequently accessed or created archives are
Xstored. In this case, the application program
Xis responsible for maintaining the relative\-path relationship
Xbetween a busy object and the corresponding archive.
X.LP
XTo save disk space,
XSuccessive versions in a line of development are stored as deltas
X(differences to the previous version).
XFor generating file deltas a new delta technique,
Xdescribed in [7]
Xis employed.
XDeltas computed by this method are about 30 percent smaller than deltas
Xgenerated by \fIdiff\fR (the standard
X.UX
Xfile comparison tool).
XThis delta technique uses characters rather than lines as atomic symbols.
X.LP
XWe use a backward delta technique (like RCS),
Xi.e. only the most recent version of each line of development is
Xstored completely.
XOlder versions can be reconstructed by successively applying
Xall deltas from the most recent to the desired version.
XIn the filesystem implementation, deltas between parallel lines of
Xdevelopment are not supported (conceptually, they should be there).
XThis is because different lines of development are stored in
Xdifferent archive files and we consider it too risky
Xto spread delta chains across different
X.UX
Xfiles.
XIf the coherence of the two files gets lost (this may happen by simply
Xmoving one file) and the chain gets broken, some revisions may
Xnot be reproducible any more.
X.LP
XDerived files are stored physically unchanged.
XTests with our delta technique showed, that it makes not much
Xsense to build deltas between binary files.
XOn calling \fIaf_savebinary\fR, the identified file is linked into the
X\*(Af subdirectory.
XAdditionally, the attribute buffer containing all the attributes
Xfor the derived file is stored in a \fIndbm\fR Database.
X.LP
XIf a saved source object shall be opened,
Xit is reconstructed and stored in a temporary file.
XDue to the unalterability of saved ASOs, the temporary file is simply
Xremoved on closing (changes have no effect on the stored ASO).
XIf one really wants to reconstruct a file, one has to create a
Xbusy object, read the data from the tmp file and write it to the
Xcreated busy object.
X.NH 2
X\*(Af on top of \*(Da
X.LP
XThe \*(Af implementation on top of \*(Da, is currently
Xunder development.
XIn this implementation, saved revisions and binary pools are stored
Xin the database.
X.LP
XIn the current implementation, the database is only used for storing the
Xinternal data (archives and binary pools) of \*(Af.
XBusy objects and temporary files (containing the data of reconstructed
Xolder versions) are still stored in the
X.UX
Xfilesystem.
X\*(Af applications have no direct access to the database.
XSimilar to the filesystem implementation, the contents of an ASO
Xhas the form of a byte stream.
XUp till now, there is no substantial difference of this impementation
Xto the filesystem implementation except that it will be slower.
X.LP
XThe actual enhancement of \*(Af on \*(Da will be the possibility for
Xapplications to use the structuring facilities of the database
Xfor their internal data (the content data of ASOs).
XBut how shall a specific ASO be created, copied, or opened, and how
Xshould a delta between two versions be constructed ?
XQuestions that can only be answered when the contents structure of the
Xcorresponding ASO is known.
XThis problem can only be solved satisfactorily by following an
Xobject oriented approach.
XAn \*(Af implementation taking this approach will provide a mechanism
Xfor the definition of ASO classes, defining specific attributes
Xand virtual operations (e.g. compute delta, open, linearize)
Xon instances of these classes.
X.LP
XAnother very practical problem is extensibility. In the current
Xstate, a \*(Da database has \fIone\fR schema where all database
Xobject types have to be defined.
XAddition of a new application with the necessity of schema
Xupdates requires the generation of an entire new database and the
X(troublesome)
Xtransfer of all the data from the old database to the new one.
X.NH 1
XThe future of \*(Af
X.LP
XWhen we made the first design of \*(Af,
Xaimed primarily at facilitating the implementation of the
X\*(sh\-toolkit,
Xwe were not aware of the power of this approach.
XEspecially the mechanism of user defined attributes
Xinspired us to think of applications that go far beyond
Xthe tasks \*(Af was originally designed for.
X.LP
XHowever, it is still a problem to make consistent use of user
Xdefined attributes. Each application has to set them explicitly.
XThe exchange of information via user defined attributes
Xhas to be subject of special agreements and naming conventions.
XA good improvement will be the introduction of some kind of
XASO definition language.
XThis would be the input for a general class manager
Xthat manages the storage of objects of well defined object classes.
XThe definition of an object class contains a specification
Xof all attributes attached to an object of this class.
XThe object classes will be part of a
Xclass hierarchy with attribute inheritance.
XThis makes
X\*(Af a basis for object\-oriented software engineering applications
Xthat deal with software objects.
XThese are able to store
Xtheir objects persistently, identify them (uniquely) and share them
Xwith other applications.
X.LP
XSubsequently we want to give an idea,
Xhow a possible class hierarchy might look like.
XExamples for classes are \fIsoftware object\fR, 
X\fIsource object\fR, \fIderived object\fR or \fIrevisible object\fR.
XThe class \fIsoftware object\fR is the basic class.
XAll other classes are derived classes inheriting the attributes
Xof \fIsoftware object\fR.
X\fISource objects\fR and \fIderived objects\fR
Xare direct subclasses of \fIsoftware object\fR.
X\fIRevisible source object\fR would be a subclass of
X\fIsource objects\fR  with the additional attributes 
X\fIgeneration number, revision number\fR and \fIversion state\fR.
XAn example for defining a class hierarchy
Xfor an object oriented database can be found in [11].
X.LP
XAnother important topic is support for \*(Af
Xapplications distributed over a local area network.
XTo support this, we need \fIpersistent keys\fR.
XUnlike the current realization of object keys which are
Xonly valid during the lifetime of the application process,
Xpersistent keys are interchangeable between processes
Xand machines.
X.NH 1
XConclusion
X.LP
XProperly speaking, \*(Af was invented by accident.
XWe needed a basic data storage system capable to hold the
Xsoftware objects we deal with, plus some information about them
Xfor use by our software configuration management toolkit.
XAfter having made about 200 attempts\(dg
X.FS
X\(dg Actually we made only four or five, but 200 sounds better
X.FE
Xto finally fix the set of attributes necessary to hold
Xsufficient information about
Xsoftware objects, we gave up and invented the user
Xdefined attributes instead.
XOne important inspiration for user defined attributes was the
Xenvironment concept known from the
X.UX
Xshell.
XOnce available, the environment is extended by some new variable
Xalmost each time a new tool is added to the system.
X.LP
XSo we defined \*(Af as an internal interface.
XWhile writing our first \*(Af applications, we got aware of
Xthe power and the insufficiencies of the mechanism of
Xapplication defined attributes.
XWe believe that many applications might benefit from this concept,
Xand that it is too valuable to be just an internal interface.
XFurther development of \*(Af will primarily go into the direction
Xdescribed in the previous chapter.
XWe are curious, where this way will lead us to.
X.NH 1
XAcknowledgement
X.PP
XThis work is part of the \*(Un project. The project is supported by the
XBundesministerium f\*:ur Forschung und Technologie 
X(Federal Ministry for Research and Technology) under grant ITS 8308.
X.KS
X.]<
X.\"Dittrich.K-1986-1
X.ds [F 1
X.]-
X.ds [A Klaus Dittrich
X.as [A ", Willi Gotthard
X.as [A ", and Peter C. Lockemann
X.ds [T DAMOKLES. A Database System for Software Engineering Environments
X.ds [J International Workshop on Advanced Programming Environments
X.ds [P 351-371
X.nr [P 1
X.ds [I IFIP WG2.4
X.ds [I Springer Verlag
X.ds [C Trondheim, Norway
X.ds [D June 1986
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Feldman.S.I.-1979-2
X.ds [F 2
X.]-
X.ds [A Stuart I. Feldman
X.ds [T MAKE - A Program for Maintaining Computer Programs
X.ds [J Software - Practice and Experience
X.ds [V 9,3
X.ds [P 255-265
X.nr [P 1
X.ds [D March 1979
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Leblang.D.B.-1985-3
X.ds [F 3
X.]-
X.ds [A David B. Leblang
X.as [A " and Gordon D. McLean, Jr.
X.ds [T Configuration Management for Large-Scale Software Development Efforts
X.ds [P 122-127
X.nr [P 1
X.ds [I GTE Laboratories
X.ds [J Workshop on Software Engineering Environments for 
X.as [J " Programming-in-the-Large
X.ds [C Harwichport, Massachusets
X.ds [D June 1985
X.nr [T 0
X.nr [A 1
X.nr [O 0
X.][ 1 journal-article
X.\"Mahler.A-1988-4
X.ds [F 4
X.]-
X.ds [A Axel Mahler
X.as [A " and Andreas Lampen
X.ds [T shape \- A Software Configuration Management Tool
X.ds [J Proceedings of the International Workshop on Software Version and Configuration Control
X.ds [I German Chapter of the ACM
X.ds [I B.G. Teubner
X.ds [P 228-243
X.nr [P 1
X.ds [C Grassau, West-Germany
X.ds [D January 1988
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Mahler.A-1988-5
X.ds [F 5
X.]-
X.ds [A Axel Mahler
X.as [A " and Andreas Lampen
X.ds [T A Toolkit for Software Configuration Management
X.ds [J Proceedings of the Spring 1988 EUUG Conference
X.ds [I European Unix systems User Group
X.ds [P 185-202
X.nr [P 1
X.ds [C London, UK
X.ds [D April 1988
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Nestor.J.R.-1986-6
X.ds [F 6
X.]-
X.ds [A John R. Nestor
X.ds [T Toward a Persistent Object Base
X.ds [J International Workshop on Advanced Programming Environments
X.ds [J Lecture Notes in Computer Science
X.ds [C Trondheim, Norway
X.ds [P 372-394
X.nr [P 1
X.ds [I Springer Verlag
X.ds [D June 1986
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Obst.W-1987-7
X.ds [F 7
X.]-
X.ds [A Wolfgang Obst
X.ds [T Delta Technique and String-to-String Correction
X.ds [J Proceedings of the 1st European Software Engineering Conference
X.ds [J Lecture Notes in Computer Science
X.ds [P 69-73
X.nr [P 1
X.ds [I Springer Verlag
X.ds [C Berlin
X.ds [D September 1987
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Rochkind.M.J.-1975-8
X.ds [F 8
X.]-
X.ds [A Marc J. Rochkind
X.ds [T The Source Code Control System
X.ds [J IEEE Transactions on Software Engineering
X.ds [V SE-1
X.ds [P 364-370
X.nr [P 1
X.ds [D 1975
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Tichy.W.F.-1985-9
X.ds [F 9
X.]-
X.ds [A Walter F. Tichy
X.ds [T RCS - A System for Version Control
X.ds [J Software - Practice and Experience
X.ds [V 15,7
X.ds [P 637-654
X.nr [P 1
X.ds [D July 1985
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Tichy.W.F.-1988-10
X.ds [F 10
X.]-
X.ds [A Walter F. Tichy
X.ds [T Tools for Software Configuration Management
X.ds [J Proceedings of the International Workshop on Software Version and Configuration Control
X.ds [P 1-20
X.nr [P 1
X.ds [I B.G. Teubner
X.ds [I German Chapter of the ACM
X.ds [C Grassau, FRG
X.ds [D January 1988
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.\"Zdonik.S.B.-1986-11
X.ds [F 11
X.]-
X.ds [A Stanley B. Zdonik
X.ds [T Version Management in an Object-Oriented Database
X.ds [J Lecture Notes in Computer Science
X.ds [J International Workshop on Advanced Programming Environments
X.ds [C Trondheim, Norway
X.ds [P 405-422
X.nr [P 1
X.ds [I Springer Verlag
X.ds [D June 1986
X.nr [T 0
X.nr [A 0
X.nr [O 0
X.][ 1 journal-article
X.]>
X.KE
END_OF_FILE
if test 46807 -ne `wc -c <'papers/lisbon.ms'`; then
    echo shar: \"'papers/lisbon.ms'\" unpacked with wrong size!
fi
# end of 'papers/lisbon.ms'
fi
echo shar: End of archive 30 \(of 33\).
cp /dev/null ark30isdone
MISSING=""
for I in 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 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 33 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.