Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999 Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999
The Ragnarok Architectural Software Configuration Management Model Henrik Bærbak Christensen Department of Computer Science University of Aarhus ˚ DK-8000 Arhus C, Denmark
[email protected] Abstract The architecture is the fundamental framework for designing and implementing large scale software, and the ability to trace and control its evolution is essential. However, many traditional software configuration management tools view ‘software’ merely as a set of files, not as an architecture. This introduces an unfortunate impedance mismatch between the design domain (architecture level) and configuration management domain (file level.) This paper presents a software configuration management model that allows tight version control and configuration management of the architecture of a software system. Essential features of the model have been implemented in a research prototype, Ragnarok. Two years of experience using Ragnarok in three, real, small- to medium sized, projects is reported. The conclusion is that the presented model is viable, feels ‘natural’ for developers, and provides good support for handling an evolving architecture.
design patterns, software architecture, etc. Still, many traditional software configuration management (SCM) systems [11, 7, 27, 24, 4] do not support the concept of software architecture directly. Software is viewed as ‘a set of files’ and stable configurations are defined implicitly as sets of file versions with a certain label or tag. This generates an unfortunate impedance mismatch between the concepts used in design and implementation (architectural level) and in configuration management (file level.) Furthermore, sets of labelled file versions can not provide unambiguous information about the evolution of the architecture itself. This paper outlines an architectural software configuration management model where the architecture is used as basis for version and configuration control. Thereby, the impedance mismatch is lessened, making the model more ‘natural’ for developers. The architectural SCM model places strong emphasis on traceability and reproducibility of configurations and architectural changes.
2. 1. Introduction The software architecture is the mental framework software designers and engineers use to design, discuss, document, and reuse software systems. Here ‘architecture’ is used in the sense ‘the logical decomposition of a system into a collection of interrelated parts’ [18]. Software development is a dynamic process and designers and developers must constantly modify and refine the architecture as new insight is gained. Consequently, an important aspect in the development process is the ability to track and control the evolution of the software architecture. In the early days of computing, a program was often contained within a single file and systems like SCCS [28] and RCS [29] provided adequate version control. Modern software is vastly more complex and to handle it, more and more emphasis is put on the underlying architecture— a trend apparent within research fields like design methods,
Architecture
A sound, logical, software design is perhaps the most important aspect in successful software development, and abstraction and hierarchy are key concepts in a good design. An abstraction is seldom an isolated entity but must be understood in its architectural context; abstractions are organised hierarchically by composition (aggregation/partwhole), and interrelated by functional dependencies (association/use) and possibly inheritance. In object-oriented architectures, abstractions are typically classes and class-categories [6]. Composition groups classes (or class-categories) into class-categories, forming a hierarchy, while dependencies relate classes functionally (e.g. that a window class uses a general-purpose rectangle class.) Abstractions require a physical manifestation, typically as source code fragments in some programming language. However, different languages use different storage schemes
0-7695-0001-3/99 $10.00 (c) 1999 IEEE
1
Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999 Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999
for the source code. Integrated environments like Smalltalk present only the logical level while the physical level is hidden. At the other extreme, the coupling in C++ is mostly based on conventions. The architectural software configuration management model views the logical level as primary and the physical level as secondary in the sense that source code fragments are attributes of architectural entities. The central unit in the model is the software component, which is an object representing an abstraction. Software components are characterised by a unique identity, CID, and a name. The actual physical implementation of the abstraction, as well as its relations (like composition and dependency) to other components, are stored as attributes. This way, a software component is a flexible building block that may represent any granularity in a system from a simple method to a full system with a complicated substructure of components.
3. Versioning Model The evolving item is the software component and each state is represented by a software component version—in essence reifying a version of an abstraction.
3.1. Software Component Version A software component version is an immutable snapshot of the state of a software component and stored in a version database. A software component version C is a tuple (CID,VID,Ssub ,Srel ) – – – –
CID is the component identity. VID is the version identity. Ssub is a set of software artifacts, defining substance. Srel is a set of references to other component version tuples fref i (Ci ); : : : ; ref j (Cj )g, defining relations. indicates the type of relation as for instance ‘composition’, ‘functional dependency’, ‘inheritance’, etc.
The component versions for a given component are arranged in a traditional version graph [30, 13]. An essential requirement of the model is that: Requirement 1 For each software component in the version database, the elements in its relation set, Srel , must be references to specific software component versions, which are present in the version database. Example: Consider a fictitious software team that is developing a small strategy game. In the game, a player controls a region of land, comprising various cities, by means of military units. The fundamental game model is implemented in a class-category, Model, that is composed of classes Terrain, City, and Unit, modelling the fundamental
Model 11
Terrain
Unit 7 9
5
City
Figure 1: Version 11 of component Model
game concepts. Figure 1 shows a milestone, Model version 11. In the figure, the version group for a component is depicted as a box with rounded corners containing the component versions (small quadrants with the version numbers inside) organised in a version graph. Solid lines going out of a component version represent composition relations, dashed lines dependencies. So, Model version 11 is composed of Terrain version 7, City version 5, and Unit version 9—and City version 5 depends on (Unit, 9) and (Terrain, 7), and so on.
3.2. Check-in For the architecture to evolve, developers modify copies of component versions in a workspace (modifying substance and/or relations.) When the resulting changes meet some criteria of completeness, they can be committed back to the version database through a check-in procedure. The architectural model version controls the full architectural context of a component by means of a transitive closure check-in algorithm. To check in a new version, the algorithm recursively traverses all relation set references, depth-first, and creates new versions of all components along paths to modified components and updates the relation set references accordingly. Example: To illustrate a check-in, consider a situation where an inner class, Weapon, is added to class Unit. After implementation and testing, a new version of Model is created in Fig. 2. The check-in is propagated to component Weapon, it substance stored and a new version identity, 1, established. A reference to (Weapon, 1) of type ‘composition relation’ is added to the relation set of Unit, and a new version 10 created. City lies on a path to a modified component and is thus checked-in with a reference to (Unit, 10) and finally Model is checked-in. No new version of Terrain is necessary, as it does not lie on a path to Weapon.
0-7695-0001-3/99 $10.00 (c) 1999 IEEE
2
Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999 Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999
Model 11
3.6. Architectural Differences
12
Terrain
Unit 7 9
5
10
6 1
City Weapon
Figure 2: Version 12 of component Model
3.3. Check-out The check-out trivially reverses the check-in process: The root component version is checked out, then the checkout is propagated recursively to all component versions referenced in the relation sets.
3.4. Consistency As is evident from Fig. 1 and 2 the component versions and their relationships can be viewed as a directed graph: Component versions are nodes and relations are arcs. Thus, any component version is root in a directed graph that identifies a bound configuration of the abstraction and its context of relations and related abstractions. The graph interpretation allows us to express a consistency requirement on the component versions in the database: Requirement 2 For any given component version in the version database, the bound configuration it defines cannot contain more than one version of the same component. If this requirement was not ensured, absurd situations could arise. For instance in Fig. 1 if (City, 5) depended upon, say, (Unit, 8) then the configuration of Model would refer to two different versions of class Unit.
3.5. Versions equal Configurations It follows from the transitive nature of the model that the concepts ‘version’ and ‘bound configuration’ are unified. Even complex configurations are identified by a single component version, like e.g. ‘Model version 11’ in Fig. 1. Thus, configurations are first class objects and the evolution of configurations is trivially recorded and accessible.
An important consequence of the model is that the software architecture itself is under strict version control. An architectural diff algorithm can recursively compute differences in the relation sets between two versions of a component and report abstractions added, deleted, or moved, and how relations have changed. This provides better overview of architectural changes than the traditional list of file contents differences. For instance, invoking the architectural diff on Model version 11 and 12 (or e.g. City version 5 and 6) would report that a new component, Weapon, has been added via a composition relation from Unit.
4.
Architectural Evolution
Whereas major architectural changes may be the responsibility of a small elite of chief designers, minor changes often have to be made by subteams or individuals in their daily work: Introducing new classes, rearranging the dependency structure, etc. When stabilised these new configurations has to be made available for integration testing. The architectural model both supports local introduction of changes as well as later integration.
4.1. Introduction of Change Introducing changes in the architecture for a part of a system is eased by the fact that the description of architecture is distributed—relations are local attributes of the components. Therefore, changes can be made by the subteam/individual with only local effect and without the potential bottleneck of a global architectural description. Example: Our game team decides to provide both sea and land terrain in the game. The developer responsible for the Terrain class decides to model this by viewing the terrain as a matrix of areas, each area being either water or land. An inner class Matrix is introduced that depends on superclass Area and subclasses Water and Land. Figure 3 shows a version of the new context of Terrain during this work; dash-dotted lines indicate inheritance relations. Other developers, working on classes Unit and City, are not disturbed by the changes in Terrain because they work with the stable class (Terrain, 7).
4.2. Integration Integration of architectural changes is performed by a check-out. Consider the change made to the Terrain class described above. When the developer has a version of the terrain class that is sufficiently stable for the rest of the team to test, the only thing needed to be communicated is the proper version identification, here version 9. The other team members can simply check-out Terrain version 9 and will automatically get the new configuration including all newly
0-7695-0001-3/99 $10.00 (c) 1999 IEEE
3
Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999 Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999
Model
Terrain 11
9
7
12 11.1
Matrix Area 2
Terrain
Unit
7 4
10
9
7.1
9.2
Water
Land 2
5
3
6 5.2
1
City
Figure 3: Class Terrain after restructuring to provide multiple terrain types introduced classes, their internal relationships, and the code fragments defining their substance. The check-out thus becomes an ‘architectural merge’: The changed architecture of component Terrain is merged into the architecture of e.g. component Unit. Note that no merge is performed on the source code level, only on the architectural level. Working with stable versions and occasionally integrating with a new milestone version is a well-proven technique. However many fast-paced, small team, development projects work with a much faster integration cycle where developers constantly integrate the newest code. A special check-out has been provided in the prototype (section 5.) to enable this working style. It recursively traverses a given configuration and checks-out the newest version on the current branch of every component unless it is currently being edited in the developer’s workspace.
4.3. Parallel development Few development efforts proceed in a strictly linear fashion. The archetypical example of non-linear development is the case where a released system needs to be bugfixed at the same time as development on the next release is in progress. In this case, the release version becomes parent in the version graph for both the bugfixed version(s) and the mainstream development version(s) i.e. a branch point. 4.3.1. Branching In keeping with the transitive nature of the architectural model, branching is propagated throughout the configuration, i.e. similar branches are created within the version graphs of all components in the configuration. This is exemplified in Fig. 4 where a variant of Model version 11 is shown. (To keep the figure small, the evolution of Terrain from Fig. 3 is left out.) This approach may sound expensive in terms of storage. However, in most components the actual source code fragments are identical in the branch and in the main line. Thus,
Weapon
Figure 4: A variant, 11.1, of version 11 of component Model only lightweight data is changed (basically a new version identification, VID, and a new relation set, Srel ), which consumes very little storage. (In the prototype this amounts to about 170 bytes although a verbose format is used.) 4.3.2. Merging Usually, the bugfixes made in a maintenance branch need to be introduced in the main development line as well. An automatic merge is often the heart of such a reconcilement process. In many traditional systems, a merge only extends to the file level building a new file version from two file versions with a common ancestor. In the architectural model the notion of merge must be extended to the architectural level as well, i.e. it must handle added and/or deleted components as well as changed relations. The algorithm for merging is as follows: Consider two versions Cr and Cd of a given component, CID. Cr is denoted the receptor version, and Cd the donator version, as the donator can be viewed as a supplier of deltas that are merged into the receptor forming a new, direct, version of the receptor. Both versions are root in a bound configuration, and the merged configuration is calculated recursively. For each component, a merged version is created based on the receptor- and donator versions. The merged relation set is a set union of the relation sets in receptor and donator, constrained by requirement 2 (a component can only appear in one version in a configuration.) Refer to the example below to see how this works in practice. To merge the substance, a merge technique must be used that understands the format of the source code fragments; like for instance traditional merge programs for textual source code. Our implementation also identifies situations where a merge can be avoided, namely in case receptor and donator versions have identical substances and relation sets. Example: Figure 5 shows an example of how merge works in practice. Here variant 11.1 of Model is donator and
0-7695-0001-3/99 $10.00 (c) 1999 IEEE
4
Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999 Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999
Model 12
11
5.1. Projects
13
11.1
Terrain
Unit
7 10
9
7.1
11 9.2
5
6
7 5.2
1
City Weapon
Figure 5: A merged version 13 of component Model from receptor version 12 and donator version 11.1 merged back into the main development line, version 12. Consider component Unit where the branched version 9.2 has a single relation, a dependency to Terrain, but the receptor has an additional composition relation to Weapon. The result is a union with both a dependency to Terrain and a composition relation to Weapon. Considering Terrain, substances and relation sets are identical in receptor- and donator versions, and thus a potential version 8 is avoided. It should be noted that any automatic merge has its limits. A merge between two versions representing radically different architectures will most likely be useless and invalid.
5. Prototype The architectural model is implemented as a subsystem in the Ragnarok software development environment [9, 10]. This subsystem has been equipped with its own, textual, interface in a stand-alone software configuration management tool called RCM. RCM has been used for more than two years in three, small- to medium-sized, projects. A number of design decisions had to be made to create a flexible prototype quickly, in order to evaluate the feasibility of the model. Major decisions include: – The substance attribute implemented as a set of RCScontrolled [29] files. The drawback is that finegrained abstractions, like individual methods in a class, are infeasible in practice. However, a large effort in implementing efficient delta storage was avoided. – Copy scheme for workspaces like in CVS [4]. This scheme does not scale up, but, again, the implementation is easy. The RCM prototype is freely available and described on WWW [8].
The first project, which has used RCM since March 1996, is ‘ConSys’ [17] . The ConSys team of three developers has been developing a Windows NT system, for controlling accelerators, storage rings, and other large distributed equipment in experimental physics. The system consists of about 130 components and more than 1100 files. The source code size is about 225.000 lines of C++ code. The second project is the BETA compiler team, four developers responsible for the development and maintenance of the Mjølner BETA compiler [1, 5], a commercial compiler for the strongly typed object oriented language BETA [21]. The development is mainly done in the BETA language itself, however the run-time system is written in C. The compiler has been under RCM control since February 1997, and consists of 35 components containing about 250 files which amounts to about 120.000 lines of code. The last project is the Ragnarok project itself. Ragnarok is about 40.000 lines of code, in about 160 files in 35 components.
5.2. Results Data has been collected from the projects mainly through guided, open-ended [26] interviews of the developers on the BETA compiler and ConSys projects. A secondary source of data has been automatically generated usage logs from RCM that have been analysed by simple statistical methods. The conclusion from both interviews and analysis of the usage data is that the architectural software configuration management approach is a viable one, at least for small- to medium sized projects. Some key points were made: Model ‘feels’ natural: The user groups readily accept the software component to represent design entities and claim a close, if not one-to-one, mapping between their design and their software component structure. They ‘think’ SCM in terms of components rather than files/directories. This claim is supported by the usage logs data where file related commands are seldom used. Focus on bound configurations: Bound configurations are of course important for milestone- and release management but the developers more emphasised the feeling of ‘security’ in the daily development cycle as backtracking to working configurations was easy. Traceable architectural evolution: To be able to trace how the architecture evolves was considered important. During the two year period, the ConSys project has more than tripled its size in terms of components and files, and the ability to make local changes to the architecture was considered essential. Intermediate versions: The teams were also asked if they found the intermediate versions created in components in-
0-7695-0001-3/99 $10.00 (c) 1999 IEEE
5
Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999 Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999
directly modified (i.e. on a path to a modified component) annoying. They did not report this a problem; it was ‘the job of the tool’ and handled adequately.
6. Discussion It should be noted that the model does not exclude the use of selection rules to make new configurations in a workspace, but rule-based selection plays a much lesser part than in many other software configuration management systems. Generally, stable subconfigurations can be communicated through their version identifications, which eliminates the need for rules to describe them. A question one may ask, is how to treat parallel work on different components that have overlapping configurations; for example if City and Unit both depend on a library component that both developers need to modify frequently. The general answer is that the branch/merge technique comes into play (section 4.3.), but the experience from the projects is, that people avoid it. The prototype warns when developers want to edit a component version that will need to branch and they can cancel the action. Instead, they retrieve the newest version before editing and avoid the branch. An important question is that of scale: Does this approach scale well to large software systems? We believe so and base our belief on the fact that human’s best tool to handle complexity and size is the well-known paradigm of ‘divide-and-conquer’. So, if a ‘well-behaved’ architecture can emerge with logical boundaries and low coupling, the architectural model should be sound as well.
7. Related Work Many traditional SCM systems [11, 27, 12, 7, 24, 4] rely on labels or tags for defining bound configurations: When creating, say a milestone, all file versions defining the milestone are tagged with a symbolic name. While tagged file version based systems are easy to understand, they suffer from a number of conceptual problems. First, tagged file versions do not convey information about the evolution of the software architecture itself. If you consider the many, radical, changes made in Terrain (Fig. 3), the tagging technique can only account for the file versions used in the two configurations of Terrain. It cannot describe the changed and newly formed relationships and components. Also, if a given file version bears the tag for one release but not the other, there are several valid causes: The file could either have been deleted or added between the two releases, or maybe someone just forgot to tag it. Secondly, conceptually a tag is an is-used-in relation (stating that ‘this version of this file is-used-in, say, release 4 of our system’)—however developers more naturally think in terms of uses relations like: Release 4 uses graphics library version 14, which uses the window class version 22 etc. As an experiment think
about how it would be to program in a modular programming language that only offered an is-used-in relation. The box construct in Gandalf [16], family in Adele [3], and the configuration language PCL [31] also allow describing physical structure as attributes of the logical structure. In contrast to our model, these focus on generic configurations through rule-based selection [13] (Adele, PCL) or a dynamically bound ‘standard’ version (Gandalf). The underlying version and configuration model in COOP/Orm [22, 23, 25] and POEM [20, 19] share the transitive flavour of our model. Both systems are focused on supporting fine-grained abstractions but are not used in reallife projects. As such, we feel that our work complements and adds credibility to COOP/Orm and POEM by reporting that architectural models are feasible in practice.
8.
Future Work
Future research proceeds in a number of directions. A strong wish is to improve the current implementation to allow larger projects to be handled. The current use of a copy scheme for workspaces is a limitation in this respect, and a future version must implement a mechanism to share versions and thereby reduce workspace storage requirements. Another important topic is collaboration and a current effort is to introduce specific support for cooperative versions [15] that allows several teams/individuals to work in parallel on overlapping configurations. The branch/merge mechanism will be used as the underlying technique but cooperative branches will be treated specially to emphasise collaborative awareness and minimise the amount of ’pollution’ of the version graph. Finally, the current work has grown out of an objectoriented software engineering context. An important exercise is to evaluate and analyse the model in a broader architectural perspective, for instance to see if the model is suitable for other architectural styles [2]. Furthermore, the model has similarity to an architecture description language (ADL) and this aspect should be explored further. Relations are not first class objects in our model, in contrast to the connector concept in ADLs, and this increased power of expressiveness should be analysed in the context of software configuration management.
9.
Conclusion
The architectural software configuration management model takes the logical software architecture as its starting point and uses this structure to ‘drive’ the version- and configuration control process. Thereby, developers can do SCM in terms of well-known concepts from the design domain. Fewer SCM specific concepts are introduced, basically only the notion of ‘version’, resulting in easier learning. The emphasis on bound configurations has as a result that the con-
0-7695-0001-3/99 $10.00 (c) 1999 IEEE
6
Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999 Proceedings of the 32nd Hawaii International Conference on System Sciences - 1999
cepts ‘version’ and ‘bound configuration’ are unified, and configurations become first class objects and are organised historically. The emphasis also results in a feeling of security in the daily development cycle as earlier, known-towork, configurations can be easily be reestablished or compared to. Finally, the architecture itself is under tight version control as the full context of abstractions and their interrelations are stored during a check-in. We generally find the results from using RCM in real projects encouraging, especially seen in the light that the prototype is still rather crude. It is a stable, viable, tool for configuration management, and provides good support for controlling and tracing the evolution of the architecture of a software system.
[14] J. Estublier, editor. Software Configuration Management, Lecture Notes in Computer Science 1005. ICSE SCM-4 and SCM-5 Workshops, Springer Verlag, 1995. [15] J. Estublier and R. Casallas. Three Dimensional Versioning. In Estublier [14], pages 118–135. [16] A. N. Habermann and D. Notkin. Gandalf: Software Development Environments. IEEE Transactions on Software Engineering, 12(12):1117–1127, dec 1986. [17] ISA. Consys. http://isals.dfi.aau.dk, 1996. ISA: Institute for Storage Ring Facilities, University of Aarhus. [18] D. A. Lamb. Introduction: Studies of Software Design. In D. A. Lamb, editor, Studies of Software Design, Lecture Notes in Computer Science 1078. ICSE’93 Workshop, Springer Verlag, 1996. [19] Y.-J. Lin and S. P. Reiss. Configuration Management in Terms of Modules. In Estublier [14].
References [1] P. Andersen, L. Bak, S. Brandt, J. L. Knudsen, O. L. Madsen, K. J. Møller, C. Nørgaard, and E. Sandvad. The Mjølner BETA System. In Object-Oriented Environments - The Mjølner Approach, pages 24–35. Prentice-Hall, 93.
[20] Y.-J. Lin and S. P. Reiss. Configuration Management with Logical Structures. In Proceedings of the 18th International Conference on Software Engineering, pages 298–307. IEEE Computer Society Press, 1996.
[2] L. Bass, P. Clements, and R. Kazman. Software Architecture in Practice. Addison-Wesley, 1998.
[21] O. L. Madsen, B. Møller-Pedersen, and K. Nygaard. ObjectOriented Programming in the BETA Programming Language. Addison Wesley, 1993.
[3] N. Belkhatir and J. Estublier. Experience with a Database of Programs. In Proceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium on Practical Software Development Environments, volume 22, pages 84–91, jan 1987. [4] B. Berliner. CVS II: Parallelizing Software Development. In USENIX, Washington D.C., 1990.
[5] http://www.daimi.aau.dk/ beta/. [6] G. Booch. Object Oriented Design. The Benjamin/Cummings Publishing Company, Inc., 1991. [7] PLATINUM CCC/Harvest Users Guide. [8] H. B. Christensen. RCM Reference Guide. Department of Computer Science, University of Aarhus, 1998. http://www.daimi.aau.dk/ hbc/Ragnarok/rcm quickref.html.
[9] H. B. Christensen. The Ragnarok Software Development Environment. In K. A. Mughal and A. L. Opdahl, editors, Proceedings of NWPER’98, Nordic Workshop on Programming Environment Research, Bergen, June 1998. Department of Information Science, University of Bergen. [10] H. B. Christensen. Utilising a Geographic Space Metaphor in a Software Development Environment. In Proceedings of EHCI’98, IFIP Working Conference on Engineering for Human-Computer Interaction, Crete, Greece, Sept. 1998. Chapman and Hall. [11] http://www.rational.com/products/clearcase/. [12] Pc-based version http://www.silcom.com/ alobba/pc vc.html.
control.
[13] R. Conradi and B. Westfechtel. Towards a Uniform Version Model for Software Configuration Management. In R. Conradi, editor, Software Configuration Management, Lecture Notes in Computer Science 1235. ICSE’97 SCM-7 Workshop, Springer Verlag, 1997.
[22] B. Magnusson and U. Asklund. Fine Grained Version Control of Configurations in COOP/Orm. In I. Sommerville, editor, Software Configuration Management, Lecture Notes in Computer Science 1167, pages 31–48. ICSE’96 SCM-6 Workshop, Springer Verlag, 1996. [23] B. Magnusson, U. Asklund, and S. Min¨or. Fine Grained Revision Control for Collaborative Software Development. In ACM SIGSOFT’93 - Symposium on the Foundations of Software Engineering, Los Angeles, California, Dec. 1993. [24] Microsoft (R) Corporation: http://www.microsoft.com/ssafe/.
Visual
SourceSafe.
[25] S. Min¨or and B. Magnusson. A model for Semi(a)Synchronous Collaborative Editing. In Proceedings of Third European Conference on Computer-Supported Cooperative Work - ECSCW’93, Milano, Italy, 1993. Kluwer Academic Press. [26] M. Q. Patton. Qualitative Evaluation Methods. Sage Publications, Beverly Hills, Calif., 1980. [27] http://www.intersolv.com/products/pvcs-vm.htm. [28] M. J. Rochkind. The Source Code Control System. IEEE Transactions on Software Engineering, 1(4), 1975. [29] W. F. Tichy. RCS – A System for Version Control. Software – Practice & Experience, 15(7):637–654, July 1985. [30] W. F. Tichy. Tools for Software Configuration Management. In J. F. H. Winkler, editor, Proceedings of the International Workshop on Software Version and Configuration Control. B. G. Teubner, Stuttgart, Jan. 1988. [31] E. Tryggeseth, B. Gulla, and R. Conradi. Modelling Systems with Variability using the PROTEUS Configuration Language. In Estublier [14].
0-7695-0001-3/99 $10.00 (c) 1999 IEEE
7