fixes for new classes
authorClaus Gittinger <cg@exept.de>
Tue, 06 Feb 1996 21:28:12 +0100
changeset 179 0df4c85ebd1f
parent 178 daae23ef8c93
child 180 215c8988be41
fixes for new classes
AbstrSCMgr.st
AbstractSourceCodeManager.st
CVSSCMgr.st
CVSSourceCodeManager.st
--- a/AbstrSCMgr.st	Fri Feb 02 17:25:01 1996 +0100
+++ b/AbstrSCMgr.st	Tue Feb 06 21:28:12 1996 +0100
@@ -128,6 +128,18 @@
 
 !AbstractSourceCodeManager class methodsFor:'private'!
 
+containerFromSourceInfo:info
+    (info includesKey:#fileName) ifTrue:[
+        ^ info at:#fileName
+    ].
+    (info includesKey:#expectedFileName) ifTrue:[
+        ^ info at:#expectedFileName
+    ].
+    ^ (info at:#classFileNameBase) , '.st'
+
+    "Modified: 6.2.1996 / 17:27:24 / cg"
+!
+
 directoryFromContainerPath:containerPath
     "given a full path as in an RCS header, extract the directory (i.e. package)."
 
@@ -193,6 +205,18 @@
     "Modified: 13.12.1995 / 13:06:03 / cg"
 !
 
+moduleFromSourceInfo:info
+    ^ info at:#module.  "/ use the modules name as CVS module
+
+    "Created: 6.2.1996 / 17:26:38 / cg"
+!
+
+packageFromSourceInfo:info
+    ^ info at:#directory.
+
+    "Created: 6.2.1996 / 17:26:23 / cg"
+!
+
 pathInRepositoryFrom:containerPath
     "this tries to extract the path within a repository, given some path
      as present in an RCS Header string.
@@ -287,67 +311,130 @@
 sourceInfoOfClass:aClass
     "helper: return a classes sourceCodeInfo"
 
-    |cls sourceInfo revInfo actualSourceFileName classFileName
-     newInfo revisionInfo container|
+    |cls binaryInfo sourceInfo revInfo actualSourceFileName classFileNameBase
+     newInfo revisionInfo container expectedFileName
+     directoryFromRev moduleFromRev fileNameFromRev directoryFromBin moduleFromBin|
 
     cls := aClass.
     cls isMeta ifTrue:[
         cls := cls soleInstance
     ].
 
+    newInfo := IdentityDictionary new.
+
     "/
     "/ the info given by the classes source ...
     "/
     revInfo := aClass revisionInfo.
+    revInfo notNil ifTrue:[
+        revInfo keysAndValuesDo:[:key :value |
+            newInfo at:key put:value
+        ]
+    ].
 
     "/
     "/ the info given by the classes binary ...
     "/ if present, we better trust that one.
+    "/ however, it only contains partial information (directory & module).
+    "/ (but is available even without a source)
     "/
-    sourceInfo := cls packageSourceCodeInfo.
-    sourceInfo isNil ifTrue:[
-        revInfo isNil ifTrue:[
-            'SOURCEMGR: class has neither source nor compiled-in info' infoPrintNL.
-            ^ nil
-        ].
-
-        container := revInfo at:#repositoryPathName ifAbsent:nil.
-        container notNil ifTrue:[
-            sourceInfo := revInfo.
-            sourceInfo at:#directory put:(self directoryFromContainerPath:container).
-            sourceInfo at:#module put:(self moduleFromContainerPath:container).
+    binaryInfo := cls packageSourceCodeInfo.
+    binaryInfo notNil ifTrue:[
+        binaryInfo keysAndValuesDo:[:key :value |
+            newInfo at:key put:value
         ]
     ].
 
+    "/
+    "/ no information
+    "/
+    (binaryInfo isNil and:[revInfo isNil]) ifTrue:[
+        'SOURCEMGR: class has neither source nor compiled-in info' infoPrintNL.
+        ^ nil
+    ].
 
     "/
-    "/ the filename I would expect from its name ...
-    "/
-    classFileName := Smalltalk fileNameForClass:aClass.
+    "/ validate for conflicts
+    "/ trust binary if in doubt
+    "/ (in case some cheater edited the version string)
+
+    revInfo notNil ifTrue:[
+        (revInfo includesKey:#repositoryPathName) ifTrue:[
+            container := revInfo at:#repositoryPathName ifAbsent:nil.
+            newInfo at:#directory put:(directoryFromRev := self directoryFromContainerPath:container).
+            newInfo at:#module put:(moduleFromRev := self moduleFromContainerPath:container).
+            fileNameFromRev := self filenameFromContainerPath:container.
+            newInfo at:#fileName put:(fileNameFromRev copyWithoutLast:2).
+
+            binaryInfo notNil ifTrue:[
+                (binaryInfo includesKey:#directory) ifTrue:[
+                    directoryFromBin := binaryInfo at:#directory.
+                    moduleFromBin := binaryInfo at:#module.
 
-    newInfo := IdentityDictionary new.
-    sourceInfo keysAndValuesDo:[:key :value |
-        newInfo at:key put:value
+                    (directoryFromBin ~= directoryFromRev 
+                    or:[moduleFromBin ~= moduleFromRev]) ifTrue:[
+                        ('SOURCEMGR: conflicting source infos (binary: ' 
+                            , directoryFromBin , '/' , moduleFromBin
+                            , ' vs. source:'
+                            , directoryFromRev , '/' , moduleFromRev
+                            , ')') infoPrintNL.
+                        newInfo at:#directory put:directoryFromBin.
+                        newInfo at:#module put:moduleFromBin.
+                    ]
+                ]
+            ].
+        ]
+    ].
+
+    "/
+    "/ the filename I'd expect from its name ...
+    "/
+    classFileNameBase := Smalltalk fileNameForClass:aClass.
+
+    (newInfo includesKey:#fileName) ifFalse:[
+        newInfo at:#fileName put:(classFileNameBase , '.st')
+    ].
+
+    "/ guess on the container
+    container isNil ifTrue:[
+        (sourceInfo includesKey:#directory) ifTrue:[
+            (sourceInfo includesKey:#module) ifTrue:[
+                (sourceInfo includesKey:#module) ifTrue:[
+                    container := (sourceInfo at:#directory)
+                                 , '/'
+                                 , (sourceInfo at:#module)
+                                 , '/'
+                                 , classFileNameBase , '.st,v'.
+                ]
+            ]
+        ]
+    ].
+
+    container notNil ifTrue:[
+        newInfo at:#repositoryPathName put:container.
     ].
 
     "/ check ..
     revInfo notNil ifTrue:[
         actualSourceFileName := revInfo at:#fileName ifAbsent:nil.
         actualSourceFileName notNil ifTrue:[
-            actualSourceFileName ~= (classFileName , '.st') ifTrue:[
-                ('SOURCEMGR: source of class ' , aClass name , ' found in ' , actualSourceFileName , ' (expected: ' , classFileName , '.st); renamed ?') infoPrintNL.
-                newInfo at:#expectedFileName put:(classFileName).
+            expectedFileName := classFileNameBase , '.st'.
+            actualSourceFileName ~= expectedFileName ifTrue:[
+                ('SOURCEMGR: source of class ' , aClass name , ' in ' , actualSourceFileName , ';') infoPrintNL.
+                ('SOURCEMGR: (expected: ' , expectedFileName , '); renamed or missing abbreviation ?') infoPrintNL.
+                ('SOURCEMGR: This may fail to autoload later if left unchanged.') infoPrintNL.
+                newInfo at:#expectedFileName put:expectedFileName.
                 newInfo at:#renamed put:true.
-                classFileName := actualSourceFileName copyWithoutLast:3
+                classFileNameBase := actualSourceFileName copyWithoutLast:3
             ]
         ]
     ].
 
-    newInfo at:#classFileName put:classFileName.
+    newInfo at:#classFileNameBase put:classFileNameBase.
     ^ newInfo
 
     "Created: 25.11.1995 / 12:40:19 / cg"
-    "Modified: 17.12.1995 / 16:03:31 / cg"
+    "Modified: 6.2.1996 / 19:25:39 / cg"
 !
 
 streamForClass:cls fileName:classFileName revision:revision directory:packageDir module:moduleDir cache:cacheIt
@@ -425,12 +512,11 @@
         ^ false
     ].
 
-    packageDir := sourceInfo at:#directory.
-    moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-    classFileName := sourceInfo at:#classFileName.
-"/    classFileName := Smalltalk fileNameForClass:aClass.
+    packageDir := self packageFromSourceInfo:sourceInfo.
+    moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+    classFileName := self containerFromSourceInfo:sourceInfo.
 
-    ^ self checkinClass:aClass fileName:(classFileName , '.st') directory:packageDir module:moduleDir logMessage:logMessage
+    ^ self checkinClass:aClass fileName:classFileName directory:packageDir module:moduleDir logMessage:logMessage
 
 
     "
@@ -438,7 +524,7 @@
     "
 
     "Created: 6.11.1995 / 18:56:00 / cg"
-    "Modified: 9.12.1995 / 21:40:44 / cg"
+    "Modified: 6.2.1996 / 17:37:20 / cg"
 !
 
 mostRecentSourceStreamForClassNamed:aClassName
@@ -449,11 +535,11 @@
         sourceInfo := self sourceInfoOfClass:cls.
     ].
     sourceInfo notNil ifTrue:[
-        packageDir := sourceInfo at:#directory.
-        moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-        classFileName := sourceInfo at:#classFileName.
+        packageDir := self packageFromSourceInfo:sourceInfo.
+        moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+        classFileName := self containerFromSourceInfo:sourceInfo.
     ] ifFalse:[
-        classFileName := Smalltalk fileNameForClass:aClassName.
+        classFileName := (Smalltalk fileNameForClass:aClassName) , '.st'.
         packageDir := Smalltalk sourceDirectoryNameOfClass:aClassName.
         moduleDir := 'stx'.
     ].
@@ -472,7 +558,7 @@
         cache:false
 
     "Created: 6.11.1995 / 16:09:06 / cg"
-    "Modified: 10.12.1995 / 01:09:06 / cg"
+    "Modified: 6.2.1996 / 17:34:57 / cg"
 !
 
 sourceStreamFor:aClass
@@ -493,32 +579,31 @@
      packageDir moduleDir sourceInfo revInfo|
 
     aRevisionStringOrNil isNil ifTrue:[
-	revision := aClass binaryRevision.
-	revision isNil ifTrue:[ 
-	    ('SOURCEMGR: class ' , aClass name , ' has no revision string') infoPrintNL.
-	    ^ nil.
-	]
+        revision := aClass binaryRevision.
+        revision isNil ifTrue:[ 
+            ('SOURCEMGR: class ' , aClass name , ' has no revision string') infoPrintNL.
+            ^ nil.
+        ]
     ] ifFalse:[
-	revision := aRevisionStringOrNil
+        revision := aRevisionStringOrNil
     ].
 
     sourceInfo := self sourceInfoOfClass:aClass.
     sourceInfo isNil ifTrue:[^ nil].
 
-    packageDir := sourceInfo at:#directory.
-    moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-    classFileName := sourceInfo at:#classFileName.
-
+    packageDir := self packageFromSourceInfo:sourceInfo.
+    moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+    classFileName := self containerFromSourceInfo:sourceInfo.
 
     ^ self 
-	streamForClass:aClass
-	fileName:classFileName 
-	revision:revision 
-	directory:packageDir 
-	module:moduleDir
-	cache:true
+        streamForClass:aClass
+        fileName:classFileName 
+        revision:revision 
+        directory:packageDir 
+        module:moduleDir
+        cache:true
 
-    "Modified: 25.11.1995 / 17:04:38 / cg"
+    "Modified: 6.2.1996 / 17:30:26 / cg"
 ! !
 
 !AbstractSourceCodeManager class methodsFor:'source code administration'!
@@ -697,23 +782,22 @@
     sourceInfo := self sourceInfoOfClass:aClass.
     sourceInfo isNil ifTrue:[^ nil].
 
-    packageDir := sourceInfo at:#directory.
-    moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-"/    classFileName := Smalltalk fileNameForClass:aClass.
-    classFileName := sourceInfo at:#classFileName.
+    packageDir := self packageFromSourceInfo:sourceInfo.
+    moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+    classFileName := self containerFromSourceInfo:sourceInfo.
 
     info := self 
         revisionLogOf:aClass
         fromRevision:rev1 
         toRevision:rev2
-        fileName:(classFileName , '.st')
+        fileName:classFileName
         directory:packageDir 
         module:moduleDir.
 
     info notNil ifTrue:[
-        (sourceInfo includesKey:#renamed) ifTrue:[
-            info at:#renamed put:(sourceInfo at:#renamed)
-        ].
+"/        (sourceInfo includesKey:#renamed) ifTrue:[
+"/            info at:#renamed put:(sourceInfo at:#renamed)
+"/        ].
         (sourceInfo includesKey:#expectedFileName) ifTrue:[
             info at:#expectedFileName put:(sourceInfo at:#expectedFileName)
         ]
@@ -726,7 +810,7 @@
     "
 
     "Created: 6.11.1995 / 18:56:00 / cg"
-    "Modified: 9.12.1995 / 22:04:08 / cg"
+    "Modified: 6.2.1996 / 17:29:05 / cg"
 !
 
 revisionLogOf:cls fromRevision:rev1 toRevision:rev2 fileName:classFileName directory:packageDir module:moduleDir 
@@ -763,11 +847,11 @@
     "helper; send the revisionlog to aStream"
 
     header ifTrue:[
-        (log at:#renamed ifAbsent:false) ifTrue:[
-            aStream nextPutAll:'  Class was probably renamed; revision info is from original class.'.
-            aStream cr; nextPutAll:'  You may have to create a new container for it.'.
-            aStream cr; cr.
-        ].
+"/        (log at:#renamed ifAbsent:false) ifTrue:[
+"/            aStream nextPutAll:'  Class was probably renamed; revision info is from original class.'.
+"/            aStream cr; nextPutAll:'  You may have to create a new container for it.'.
+"/            aStream cr; cr.
+"/        ].
 
         aStream nextPutAll:'  Total revisions: '; nextPutAll:(log at:#numberOfRevisions) printString; cr.
         aStream nextPutAll:'  Newest revision: '; nextPutAll:(log at:#newestRevision) printString; cr.
@@ -791,7 +875,7 @@
     ].
 
     "Created: 16.11.1995 / 13:25:30 / cg"
-    "Modified: 10.12.1995 / 16:51:15 / cg"
+    "Modified: 6.2.1996 / 17:24:38 / cg"
 !
 
 writeRevisionLogOf:aClass fromRevision:rev1 toRevision:rev2 to:aStream
@@ -827,6 +911,6 @@
 !AbstractSourceCodeManager class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic3/Attic/AbstrSCMgr.st,v 1.41 1996-01-18 00:21:07 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic3/Attic/AbstrSCMgr.st,v 1.42 1996-02-06 20:27:43 cg Exp $'
 ! !
 AbstractSourceCodeManager initialize!
--- a/AbstractSourceCodeManager.st	Fri Feb 02 17:25:01 1996 +0100
+++ b/AbstractSourceCodeManager.st	Tue Feb 06 21:28:12 1996 +0100
@@ -128,6 +128,18 @@
 
 !AbstractSourceCodeManager class methodsFor:'private'!
 
+containerFromSourceInfo:info
+    (info includesKey:#fileName) ifTrue:[
+        ^ info at:#fileName
+    ].
+    (info includesKey:#expectedFileName) ifTrue:[
+        ^ info at:#expectedFileName
+    ].
+    ^ (info at:#classFileNameBase) , '.st'
+
+    "Modified: 6.2.1996 / 17:27:24 / cg"
+!
+
 directoryFromContainerPath:containerPath
     "given a full path as in an RCS header, extract the directory (i.e. package)."
 
@@ -193,6 +205,18 @@
     "Modified: 13.12.1995 / 13:06:03 / cg"
 !
 
+moduleFromSourceInfo:info
+    ^ info at:#module.  "/ use the modules name as CVS module
+
+    "Created: 6.2.1996 / 17:26:38 / cg"
+!
+
+packageFromSourceInfo:info
+    ^ info at:#directory.
+
+    "Created: 6.2.1996 / 17:26:23 / cg"
+!
+
 pathInRepositoryFrom:containerPath
     "this tries to extract the path within a repository, given some path
      as present in an RCS Header string.
@@ -287,67 +311,130 @@
 sourceInfoOfClass:aClass
     "helper: return a classes sourceCodeInfo"
 
-    |cls sourceInfo revInfo actualSourceFileName classFileName
-     newInfo revisionInfo container|
+    |cls binaryInfo sourceInfo revInfo actualSourceFileName classFileNameBase
+     newInfo revisionInfo container expectedFileName
+     directoryFromRev moduleFromRev fileNameFromRev directoryFromBin moduleFromBin|
 
     cls := aClass.
     cls isMeta ifTrue:[
         cls := cls soleInstance
     ].
 
+    newInfo := IdentityDictionary new.
+
     "/
     "/ the info given by the classes source ...
     "/
     revInfo := aClass revisionInfo.
+    revInfo notNil ifTrue:[
+        revInfo keysAndValuesDo:[:key :value |
+            newInfo at:key put:value
+        ]
+    ].
 
     "/
     "/ the info given by the classes binary ...
     "/ if present, we better trust that one.
+    "/ however, it only contains partial information (directory & module).
+    "/ (but is available even without a source)
     "/
-    sourceInfo := cls packageSourceCodeInfo.
-    sourceInfo isNil ifTrue:[
-        revInfo isNil ifTrue:[
-            'SOURCEMGR: class has neither source nor compiled-in info' infoPrintNL.
-            ^ nil
-        ].
-
-        container := revInfo at:#repositoryPathName ifAbsent:nil.
-        container notNil ifTrue:[
-            sourceInfo := revInfo.
-            sourceInfo at:#directory put:(self directoryFromContainerPath:container).
-            sourceInfo at:#module put:(self moduleFromContainerPath:container).
+    binaryInfo := cls packageSourceCodeInfo.
+    binaryInfo notNil ifTrue:[
+        binaryInfo keysAndValuesDo:[:key :value |
+            newInfo at:key put:value
         ]
     ].
 
+    "/
+    "/ no information
+    "/
+    (binaryInfo isNil and:[revInfo isNil]) ifTrue:[
+        'SOURCEMGR: class has neither source nor compiled-in info' infoPrintNL.
+        ^ nil
+    ].
 
     "/
-    "/ the filename I would expect from its name ...
-    "/
-    classFileName := Smalltalk fileNameForClass:aClass.
+    "/ validate for conflicts
+    "/ trust binary if in doubt
+    "/ (in case some cheater edited the version string)
+
+    revInfo notNil ifTrue:[
+        (revInfo includesKey:#repositoryPathName) ifTrue:[
+            container := revInfo at:#repositoryPathName ifAbsent:nil.
+            newInfo at:#directory put:(directoryFromRev := self directoryFromContainerPath:container).
+            newInfo at:#module put:(moduleFromRev := self moduleFromContainerPath:container).
+            fileNameFromRev := self filenameFromContainerPath:container.
+            newInfo at:#fileName put:(fileNameFromRev copyWithoutLast:2).
+
+            binaryInfo notNil ifTrue:[
+                (binaryInfo includesKey:#directory) ifTrue:[
+                    directoryFromBin := binaryInfo at:#directory.
+                    moduleFromBin := binaryInfo at:#module.
 
-    newInfo := IdentityDictionary new.
-    sourceInfo keysAndValuesDo:[:key :value |
-        newInfo at:key put:value
+                    (directoryFromBin ~= directoryFromRev 
+                    or:[moduleFromBin ~= moduleFromRev]) ifTrue:[
+                        ('SOURCEMGR: conflicting source infos (binary: ' 
+                            , directoryFromBin , '/' , moduleFromBin
+                            , ' vs. source:'
+                            , directoryFromRev , '/' , moduleFromRev
+                            , ')') infoPrintNL.
+                        newInfo at:#directory put:directoryFromBin.
+                        newInfo at:#module put:moduleFromBin.
+                    ]
+                ]
+            ].
+        ]
+    ].
+
+    "/
+    "/ the filename I'd expect from its name ...
+    "/
+    classFileNameBase := Smalltalk fileNameForClass:aClass.
+
+    (newInfo includesKey:#fileName) ifFalse:[
+        newInfo at:#fileName put:(classFileNameBase , '.st')
+    ].
+
+    "/ guess on the container
+    container isNil ifTrue:[
+        (sourceInfo includesKey:#directory) ifTrue:[
+            (sourceInfo includesKey:#module) ifTrue:[
+                (sourceInfo includesKey:#module) ifTrue:[
+                    container := (sourceInfo at:#directory)
+                                 , '/'
+                                 , (sourceInfo at:#module)
+                                 , '/'
+                                 , classFileNameBase , '.st,v'.
+                ]
+            ]
+        ]
+    ].
+
+    container notNil ifTrue:[
+        newInfo at:#repositoryPathName put:container.
     ].
 
     "/ check ..
     revInfo notNil ifTrue:[
         actualSourceFileName := revInfo at:#fileName ifAbsent:nil.
         actualSourceFileName notNil ifTrue:[
-            actualSourceFileName ~= (classFileName , '.st') ifTrue:[
-                ('SOURCEMGR: source of class ' , aClass name , ' found in ' , actualSourceFileName , ' (expected: ' , classFileName , '.st); renamed ?') infoPrintNL.
-                newInfo at:#expectedFileName put:(classFileName).
+            expectedFileName := classFileNameBase , '.st'.
+            actualSourceFileName ~= expectedFileName ifTrue:[
+                ('SOURCEMGR: source of class ' , aClass name , ' in ' , actualSourceFileName , ';') infoPrintNL.
+                ('SOURCEMGR: (expected: ' , expectedFileName , '); renamed or missing abbreviation ?') infoPrintNL.
+                ('SOURCEMGR: This may fail to autoload later if left unchanged.') infoPrintNL.
+                newInfo at:#expectedFileName put:expectedFileName.
                 newInfo at:#renamed put:true.
-                classFileName := actualSourceFileName copyWithoutLast:3
+                classFileNameBase := actualSourceFileName copyWithoutLast:3
             ]
         ]
     ].
 
-    newInfo at:#classFileName put:classFileName.
+    newInfo at:#classFileNameBase put:classFileNameBase.
     ^ newInfo
 
     "Created: 25.11.1995 / 12:40:19 / cg"
-    "Modified: 17.12.1995 / 16:03:31 / cg"
+    "Modified: 6.2.1996 / 19:25:39 / cg"
 !
 
 streamForClass:cls fileName:classFileName revision:revision directory:packageDir module:moduleDir cache:cacheIt
@@ -425,12 +512,11 @@
         ^ false
     ].
 
-    packageDir := sourceInfo at:#directory.
-    moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-    classFileName := sourceInfo at:#classFileName.
-"/    classFileName := Smalltalk fileNameForClass:aClass.
+    packageDir := self packageFromSourceInfo:sourceInfo.
+    moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+    classFileName := self containerFromSourceInfo:sourceInfo.
 
-    ^ self checkinClass:aClass fileName:(classFileName , '.st') directory:packageDir module:moduleDir logMessage:logMessage
+    ^ self checkinClass:aClass fileName:classFileName directory:packageDir module:moduleDir logMessage:logMessage
 
 
     "
@@ -438,7 +524,7 @@
     "
 
     "Created: 6.11.1995 / 18:56:00 / cg"
-    "Modified: 9.12.1995 / 21:40:44 / cg"
+    "Modified: 6.2.1996 / 17:37:20 / cg"
 !
 
 mostRecentSourceStreamForClassNamed:aClassName
@@ -449,11 +535,11 @@
         sourceInfo := self sourceInfoOfClass:cls.
     ].
     sourceInfo notNil ifTrue:[
-        packageDir := sourceInfo at:#directory.
-        moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-        classFileName := sourceInfo at:#classFileName.
+        packageDir := self packageFromSourceInfo:sourceInfo.
+        moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+        classFileName := self containerFromSourceInfo:sourceInfo.
     ] ifFalse:[
-        classFileName := Smalltalk fileNameForClass:aClassName.
+        classFileName := (Smalltalk fileNameForClass:aClassName) , '.st'.
         packageDir := Smalltalk sourceDirectoryNameOfClass:aClassName.
         moduleDir := 'stx'.
     ].
@@ -472,7 +558,7 @@
         cache:false
 
     "Created: 6.11.1995 / 16:09:06 / cg"
-    "Modified: 10.12.1995 / 01:09:06 / cg"
+    "Modified: 6.2.1996 / 17:34:57 / cg"
 !
 
 sourceStreamFor:aClass
@@ -493,32 +579,31 @@
      packageDir moduleDir sourceInfo revInfo|
 
     aRevisionStringOrNil isNil ifTrue:[
-	revision := aClass binaryRevision.
-	revision isNil ifTrue:[ 
-	    ('SOURCEMGR: class ' , aClass name , ' has no revision string') infoPrintNL.
-	    ^ nil.
-	]
+        revision := aClass binaryRevision.
+        revision isNil ifTrue:[ 
+            ('SOURCEMGR: class ' , aClass name , ' has no revision string') infoPrintNL.
+            ^ nil.
+        ]
     ] ifFalse:[
-	revision := aRevisionStringOrNil
+        revision := aRevisionStringOrNil
     ].
 
     sourceInfo := self sourceInfoOfClass:aClass.
     sourceInfo isNil ifTrue:[^ nil].
 
-    packageDir := sourceInfo at:#directory.
-    moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-    classFileName := sourceInfo at:#classFileName.
-
+    packageDir := self packageFromSourceInfo:sourceInfo.
+    moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+    classFileName := self containerFromSourceInfo:sourceInfo.
 
     ^ self 
-	streamForClass:aClass
-	fileName:classFileName 
-	revision:revision 
-	directory:packageDir 
-	module:moduleDir
-	cache:true
+        streamForClass:aClass
+        fileName:classFileName 
+        revision:revision 
+        directory:packageDir 
+        module:moduleDir
+        cache:true
 
-    "Modified: 25.11.1995 / 17:04:38 / cg"
+    "Modified: 6.2.1996 / 17:30:26 / cg"
 ! !
 
 !AbstractSourceCodeManager class methodsFor:'source code administration'!
@@ -697,23 +782,22 @@
     sourceInfo := self sourceInfoOfClass:aClass.
     sourceInfo isNil ifTrue:[^ nil].
 
-    packageDir := sourceInfo at:#directory.
-    moduleDir := sourceInfo at:#module.  "/ use the modules name as CVS module
-"/    classFileName := Smalltalk fileNameForClass:aClass.
-    classFileName := sourceInfo at:#classFileName.
+    packageDir := self packageFromSourceInfo:sourceInfo.
+    moduleDir := self moduleFromSourceInfo:sourceInfo.  "/ use the modules name as CVS module
+    classFileName := self containerFromSourceInfo:sourceInfo.
 
     info := self 
         revisionLogOf:aClass
         fromRevision:rev1 
         toRevision:rev2
-        fileName:(classFileName , '.st')
+        fileName:classFileName
         directory:packageDir 
         module:moduleDir.
 
     info notNil ifTrue:[
-        (sourceInfo includesKey:#renamed) ifTrue:[
-            info at:#renamed put:(sourceInfo at:#renamed)
-        ].
+"/        (sourceInfo includesKey:#renamed) ifTrue:[
+"/            info at:#renamed put:(sourceInfo at:#renamed)
+"/        ].
         (sourceInfo includesKey:#expectedFileName) ifTrue:[
             info at:#expectedFileName put:(sourceInfo at:#expectedFileName)
         ]
@@ -726,7 +810,7 @@
     "
 
     "Created: 6.11.1995 / 18:56:00 / cg"
-    "Modified: 9.12.1995 / 22:04:08 / cg"
+    "Modified: 6.2.1996 / 17:29:05 / cg"
 !
 
 revisionLogOf:cls fromRevision:rev1 toRevision:rev2 fileName:classFileName directory:packageDir module:moduleDir 
@@ -763,11 +847,11 @@
     "helper; send the revisionlog to aStream"
 
     header ifTrue:[
-        (log at:#renamed ifAbsent:false) ifTrue:[
-            aStream nextPutAll:'  Class was probably renamed; revision info is from original class.'.
-            aStream cr; nextPutAll:'  You may have to create a new container for it.'.
-            aStream cr; cr.
-        ].
+"/        (log at:#renamed ifAbsent:false) ifTrue:[
+"/            aStream nextPutAll:'  Class was probably renamed; revision info is from original class.'.
+"/            aStream cr; nextPutAll:'  You may have to create a new container for it.'.
+"/            aStream cr; cr.
+"/        ].
 
         aStream nextPutAll:'  Total revisions: '; nextPutAll:(log at:#numberOfRevisions) printString; cr.
         aStream nextPutAll:'  Newest revision: '; nextPutAll:(log at:#newestRevision) printString; cr.
@@ -791,7 +875,7 @@
     ].
 
     "Created: 16.11.1995 / 13:25:30 / cg"
-    "Modified: 10.12.1995 / 16:51:15 / cg"
+    "Modified: 6.2.1996 / 17:24:38 / cg"
 !
 
 writeRevisionLogOf:aClass fromRevision:rev1 toRevision:rev2 to:aStream
@@ -827,6 +911,6 @@
 !AbstractSourceCodeManager class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic3/AbstractSourceCodeManager.st,v 1.41 1996-01-18 00:21:07 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic3/AbstractSourceCodeManager.st,v 1.42 1996-02-06 20:27:43 cg Exp $'
 ! !
 AbstractSourceCodeManager initialize!
--- a/CVSSCMgr.st	Fri Feb 02 17:25:01 1996 +0100
+++ b/CVSSCMgr.st	Tue Feb 06 21:28:12 1996 +0100
@@ -321,10 +321,20 @@
     "/ do not make the string below into one string;
     "/ RCS would expand it into a wrong rev-string
 
+    |nm|
+
+    nm := fileName.
+    (nm endsWith:',v') ifTrue:[
+        nm := nm copyWithoutLast:2
+    ].
+    (nm endsWith:'.st') ifFalse:[
+        nm := nm , '.st'
+    ].
+
     ^ '$' , 'Header: ' , CVSRoot , '/' , moduleDir , '/' , packageDir , '/' , fileName , ',v $'
 
     "Created: 9.12.1995 / 21:28:11 / cg"
-    "Modified: 12.12.1995 / 19:41:11 / cg"
+    "Modified: 6.2.1996 / 16:43:53 / cg"
 !
 
 releaseAndRemove:tempdir outputTo:outputFilename
@@ -422,32 +432,32 @@
     className := cls name.
 
     merge ifTrue:[
-	revision := cls revision.
-	revision isNil ifTrue:[ 
-	    ('CVSMGR: class ' , className, ' has no revision string') errorPrintNL.
-	    (self confirm:('class ' , className, ' has no (usable) revision string.\\check in as newest ?') withCRs)
-	    ifFalse:[
-		^ false.
-	    ].
-	].
-	(binRevision := cls binaryRevision) notNil ifTrue:[
-	    revision ~= binRevision ifTrue:[
-		('CVSMGR: class ' , className , ' is based upon ' , binRevision , ' but has revision ' , revision) infoPrintNL
-	    ]
-	]
+        revision := cls revision.
+        revision isNil ifTrue:[ 
+            ('CVSMGR: class ' , className, ' has no revision string') errorPrintNL.
+            (self confirm:('class ' , className, ' has no (usable) revision string.\\check in as newest ?') withCRs)
+            ifFalse:[
+                ^ false.
+            ].
+        ].
+        (binRevision := cls binaryRevision) notNil ifTrue:[
+            revision ~= binRevision ifTrue:[
+                ('CVSMGR: class ' , className , ' is based upon ' , binRevision , ' but has revision ' , revision) infoPrintNL
+            ]
+        ]
     ].
     revision isNil ifTrue:[
-	revision := '1.0'
+        revision := '1.0'
     ].
 
     logMsg := logMessage.
     (logMsg isNil or:[logMsg isEmpty]) ifTrue:[
-	logMsg := 'checkin from browser'.
+        logMsg := 'checkin from browser'.
     ].
 
     cmdOut := Filename newTemporary.
     cmdOut exists ifTrue:[
-	cmdOut remove.
+        cmdOut remove.
     ].
 
     "/
@@ -475,11 +485,11 @@
     time := time addSeconds:(time utcOffset).
 
     self createEntryFor:checkoutName 
-	 in:(tempdir construct:modulePath) 
-	 revision:revision
-	 date:(self cvsTimeString:time)
-	 special:''
-	 overwrite:true.
+         in:(tempdir construct:modulePath) 
+         revision:revision
+         date:(self cvsTimeString:time)
+         special:''
+         overwrite:true.
 
     "/
     "/ copy-over our current version
@@ -488,9 +498,9 @@
 "/ ('move over: ' , cmd) infoPrintNL.
     (OperatingSystem executeCommand:cmd) ifFalse:[
 "/        'failed: ' errorPrint. cmd errorPrintNL.
-	tempdir recursiveRemove.
-	'CVSMGR: cannot copy-over filedOut class source' errorPrintNL.
-	^ false.
+        tempdir recursiveRemove.
+        'CVSMGR: cannot copy-over filedOut class source' errorPrintNL.
+        ^ false.
     ].
 
 merge ifTrue:[
@@ -502,15 +512,15 @@
 
     cmd := 'cd ' , tempdir name , ';cvs -d ', CVSRoot, ' update ' , checkoutName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
-	tempdir recursiveRemove.
-	cmdOut remove.
-	'CVSMGR: cannot merge current source with repository version' errorPrintNL.
-	^ false.
+        'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
+        tempdir recursiveRemove.
+        cmdOut remove.
+        'CVSMGR: cannot merge current source with repository version' errorPrintNL.
+        ^ false.
     ].
 
     "/
@@ -520,26 +530,29 @@
     "/   C xxx   -> a conflict occured and the differences have been merged into the source
     "/              needs special action
     "/
-    whatHappened := cmdOut contentsOfEntireFile asString.
+    cmdOut fileSize > 0 ifTrue:[
+        whatHappened := cmdOut contentsOfEntireFile asString.
+    ].
     cmdOut remove.
 
+    (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
+        "/
+        "/ no change
+        "/
+        tempdir recursiveRemove.
+        Transcript showCr:'no change in ' , className , ' (repository unchanged)'.
+        self information:'nothing changed in ' , className.
+        ^ true
+    ].
+
     Verbose == true ifTrue:[
-	('CVSMGR: result is: ' , whatHappened) infoPrintNL.
-    ].
-    (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
-	"/
-	"/ no change
-	"/
-	tempdir recursiveRemove.
-	Transcript showCr:'no change in ' , className , ' (repository unchanged)'.
-	self information:'nothing changed in ' , className.
-	^ true
+        ('CVSMGR: result is: ' , whatHappened) infoPrintNL.
     ].
 
     revision isNil ifTrue:[
-	changeLog := self revisionLogOf:cls.
+        changeLog := self revisionLogOf:cls.
     ] ifFalse:[
-	changeLog := self revisionLogOf:cls fromRevision:(self revisionAfter:revision) toRevision:nil.
+        changeLog := self revisionLogOf:cls fromRevision:(self revisionAfter:revision) toRevision:nil.
     ].
     s := WriteStream on:String new.
     self writeRevisionLogMessagesFrom:changeLog withHeader:false to:s.
@@ -547,42 +560,42 @@
     didMerge := false.
 
     (whatHappened startsWith:'M ') ifTrue:[
-	"/
-	"/ merged in changes
-	"/
-	(changeLog at:#revisions) isEmpty ifTrue:[
-	    "/
-	    "/ pretty good - nothing has changed in the meanwhile
-	    "/
-	    Transcript showCr:'checking in ' , className , ' ...'
-	] ifFalse:[
-	    "/
-	    "/ someone else has changed things in the meanwhile, but there is no conflict
-	    "/ and version have been merged.
-	    "/
-	    didMerge := true.
-	    changesAsLogged := changesAsLogged asCollectionOfLines.
+        "/
+        "/ merged in changes
+        "/
+        (changeLog at:#revisions) isEmpty ifTrue:[
+            "/
+            "/ pretty good - nothing has changed in the meanwhile
+            "/
+            Transcript showCr:'checking in ' , className , ' ...'
+        ] ifFalse:[
+            "/
+            "/ someone else has changed things in the meanwhile, but there is no conflict
+            "/ and version have been merged.
+            "/
+            didMerge := true.
+            changesAsLogged := changesAsLogged asCollectionOfLines.
 
-	    s := WriteStream on:String new.
-	    cls fileOutOn:s withTimeStamp:false.
-	    mySource := s contents asString.
-	    mergedSource := (tempdir name , '/' , checkoutName) asFilename readStream contents asString.
+            s := WriteStream on:String new.
+            cls fileOutOn:s withTimeStamp:false.
+            mySource := s contents asString.
+            mergedSource := (tempdir name , '/' , checkoutName) asFilename readStream contents asString.
 
-	    mySource = mergedSource ifTrue:[
-		msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
+            mySource = mergedSource ifTrue:[
+                msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
 
 I have merged your version with the newest repository version, 
 and found no differences between the result and your current version
 (i.e. your version seemed up-to-date).'.
 
-		self checkinTroubleDialog:'Merging versions'
-			       message:msg 
-			       log:changesAsLogged
-			       abortable:false 
-			       option:nil.
-		didMerge := false.
-	    ] ifFalse:[
-		msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
+                self checkinTroubleDialog:'Merging versions'
+                               message:msg 
+                               log:changesAsLogged
+                               abortable:false 
+                               option:nil.
+                didMerge := false.
+            ] ifFalse:[
+                msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
 
 If you continue, your new changes (based upon rev. ' , revision printString , ') will be MERGED
 into the newest revision. This will combine the other version with your changes
@@ -597,25 +610,25 @@
 
 Continue ?'.
 
-		answer := self checkinTroubleDialog:'Merging versions'
-			       message:msg 
-			       log:changesAsLogged
-			       abortable:true
-			       option:'stop - see first'.
-		answer ~~ true ifTrue:[
-		    answer == #option ifTrue:[
-			DiffTextView 
-			    openOn:mySource
-			    label:'current version'
-			    and:mergedSource
-			    label:'merged version'.
+                answer := self checkinTroubleDialog:'Merging versions'
+                               message:msg 
+                               log:changesAsLogged
+                               abortable:true
+                               option:'stop - see first'.
+                answer ~~ true ifTrue:[
+                    answer == #option ifTrue:[
+                        DiffTextView 
+                            openOn:mySource
+                            label:'current version'
+                            and:mergedSource
+                            label:'merged version'.
                             
-		    ].
-		    Transcript showCr:'checkin aborted - (no merge; repository unchanged)'.
-		    tempdir recursiveRemove.
-		    ^ false.
-		].
-	    ].
+                    ].
+                    Transcript showCr:'checkin aborted - (no merge; repository unchanged)'.
+                    tempdir recursiveRemove.
+                    ^ false.
+                ].
+            ].
 
 "/                changesAsLogged := (changesAsLogged asStringCollection collect:[:line | line withTabsExpanded]) asString.
 "/                msg := 'The source of ' , className , ' has been changed in the meanwhile as follows:
@@ -637,18 +650,18 @@
 "/                    tempdir recursiveRemove.
 "/                    ^ false.
 "/                ].
-	    Transcript showCr:'checking in ' , className , ' (merged other changes) ...'
-	]
+            Transcript showCr:'checking in ' , className , ' (merged other changes) ...'
+        ]
     ] ifFalse:[
-	(whatHappened startsWith:'C ') ifTrue:[
-	    "/
-	    "/ conflict; someone else checked in something in the meanwhile,
-	    "/ and there is a conflict between this version and the checked in version.
-	    "/
+        (whatHappened startsWith:'C ') ifTrue:[
+            "/
+            "/ conflict; someone else checked in something in the meanwhile,
+            "/ and there is a conflict between this version and the checked in version.
+            "/
 
-	    changesAsLogged := changesAsLogged asCollectionOfLines.
+            changesAsLogged := changesAsLogged asCollectionOfLines.
 
-	    msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
+            msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
 
 Your new changes (based upon rev. ' , revision printString , ') CONFLICT with those changes.
 
@@ -656,44 +669,44 @@
 and change your methods avoiding conflicts. The checkin again.
 '.
 
-	    (self checkinTroubleDialog:'Version conflict'
-		 message:msg 
-		 log:changesAsLogged
-		 abortable:false
-		 option:'show conflicts') == #option ifTrue:[
-		"/
-		"/ for now, show the conflicts in a dump view
-		"/ Later, there will be a 3-way DiffTextView ...
-		"/
-		Diff3TextView
-		    openOnMergedText:(tempdir name , '/' , checkoutName) asFilename readStream contents 
-		    label:'original' label:'repository' label:'your version'. 
+            (self checkinTroubleDialog:'Version conflict'
+                 message:msg 
+                 log:changesAsLogged
+                 abortable:false
+                 option:'show conflicts') == #option ifTrue:[
+                "/
+                "/ for now, show the conflicts in a dump view
+                "/ Later, there will be a 3-way DiffTextView ...
+                "/
+                Diff3TextView
+                    openOnMergedText:(tempdir name , '/' , checkoutName) asFilename readStream contents 
+                    label:'original' label:'repository' label:'your version'. 
 "/                TextView 
 "/                    openWith:(tempdir name , '/' , checkoutName) asFilename readStream contents
 "/                    title:'conflicts'.
-	    ].
+            ].
 
 "/                changesAsLogged := (changesAsLogged asCollectionOfLines asStringCollection collect:[:line | line withTabsExpanded]) asString.
 "/                self warn:'The source of ' , className , ' has been changed in the meanwhile as follows:
 "/' , changesAsLogged , '
 "/Your new changes (based upon rev. ' , revision , ') CONFLICT with those changes - please fix.'.
 
-	    'CVSMGR: cannot (for now) checkin; conflicts found' errorPrintNL.
-	    Transcript showCr:'checkin of ' , className , ' aborted (conflicting changes; repository unchanged)'.
-	    tempdir recursiveRemove.
-	    ^ false.
-	] ifFalse:[
-	    "/
-	    "/ unexpected
-	    "/
-	    self warn:'unexpected message from CVS:
+            'CVSMGR: cannot (for now) checkin; conflicts found' errorPrintNL.
+            Transcript showCr:'checkin of ' , className , ' aborted (conflicting changes; repository unchanged)'.
+            tempdir recursiveRemove.
+            ^ false.
+        ] ifFalse:[
+            "/
+            "/ unexpected
+            "/
+            self warn:'unexpected message from CVS:
 ' , whatHappened , '
 
 No checkin performed.'.
-	    Transcript showCr:'*** cannot checkin ' , className , ' (unexpected CVS response; repository unchanged)'.
-	    tempdir recursiveRemove.
-	    ^ false.
-	]
+            Transcript showCr:'*** cannot checkin ' , className , ' (unexpected CVS response; repository unchanged)'.
+            tempdir recursiveRemove.
+            ^ false.
+        ]
     ].
 ].
 
@@ -705,25 +718,33 @@
     logMsg := logMsg replChar:$"  withString:'\"'.
     cmd := 'cd ' , tempdir name , ';cvs -d ', CVSRoot, ' commit -m "', logMsg ,'" ' , checkoutName, ' 2> ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	Verbose == true ifTrue:[
-	    'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
-	].
-	whatHappened := cmdOut contentsOfEntireFile asString.
-	self warn:'The following problem was reported by cvs:
+        Verbose == true ifTrue:[
+            'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
+        ].
+        cmdOut fileSize > 0 ifTrue:[
+            whatHappened := cmdOut contentsOfEntireFile asString.
+        ] ifFalse:[
+            whatHappened := '<< no message >>'
+        ].
+        self warn:'The following problem was reported by cvs:
 
 ' , whatHappened , '
 
 The class has NOT been checked into the repository.'.
 
        'CVSMGR: cannot checkin modified class source' errorPrintNL.
-	cmdOut remove.
-	tempdir recursiveRemove.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ^ false.
     ].
-    whatHappened := cmdOut contentsOfEntireFile asString.
+    cmdOut fileSize > 0 ifTrue:[
+        whatHappened := cmdOut contentsOfEntireFile asString.
+    ] ifFalse:[
+        whatHappened := nil
+    ].
 
     tempdir recursiveRemove.
     cmdOut remove.
@@ -733,16 +754,16 @@
     "/
 
     (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
-	'CVSMGR: oops - unexpected empty checkin command output' errorPrintNL.
+        'CVSMGR: oops - unexpected empty checkin command output' errorPrintNL.
     ] ifFalse:[
-	whatHappened := whatHappened asCollectionOfLines asStringCollection.
-	idx := whatHappened indexOfLineStartingWith:'new revision:'.
-	idx == 0 ifTrue:[
-	    'CVSMGR: oops - unexpected checkin command output (no new-revision info)' errorPrintNL.
-	] ifFalse:[
-	    l := whatHappened at:idx.
-	    newRevision := (l copyFrom:14 to:(l indexOf:$; startingAt:14)-1) withoutSpaces.
-	]
+        whatHappened := whatHappened asCollectionOfLines asStringCollection.
+        idx := whatHappened indexOfLineStartingWith:'new revision:'.
+        idx == 0 ifTrue:[
+            'CVSMGR: oops - unexpected checkin command output (no new-revision info)' errorPrintNL.
+        ] ifFalse:[
+            l := whatHappened at:idx.
+            newRevision := (l copyFrom:14 to:(l indexOf:$; startingAt:14)-1) withoutSpaces.
+        ]
     ].
 
     "/
@@ -760,24 +781,24 @@
     "/    If we later checkin again, the new checkin will be again based on the current revision
     "/
     newRevision notNil ifTrue:[
-	didMerge ifFalse:[
-	    self activityNotification:'fetch revision number'.
+        didMerge ifFalse:[
+            self activityNotification:'fetch revision number'.
 
-	    changeLog := self revisionLogOf:cls fromRevision:newRevision toRevision:newRevision.
-	    (changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
-		'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
-	    ] ifFalse:[
-		entry := (changeLog at:#revisions) first.
-		newString := self revisionStringFromLog:changeLog entry:entry.
-		cls updateVersionMethodFor:newString.
-		cls revision ~= newRevision ifTrue:[
-		    'CVSMGR: oops - failed to update revisionString' errorPrintNL
-		]
-	    ]
-	] ifTrue:[
-	    newString := self updatedRevisionStringOf:cls forRevision:nil with:cls revisionString.
-	    cls updateVersionMethodFor:newString.
-	].
+            changeLog := self revisionLogOf:cls fromRevision:newRevision toRevision:newRevision.
+            (changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
+                'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
+            ] ifFalse:[
+                entry := (changeLog at:#revisions) first.
+                newString := self revisionStringFromLog:changeLog entry:entry.
+                cls updateVersionMethodFor:newString.
+                cls revision ~= newRevision ifTrue:[
+                    'CVSMGR: oops - failed to update revisionString' errorPrintNL
+                ]
+            ]
+        ] ifTrue:[
+            newString := self updatedRevisionStringOf:cls forRevision:nil with:cls revisionString.
+            cls updateVersionMethodFor:newString.
+        ].
     ].
 
     Class addChangeRecordForClassCheckIn:cls.
@@ -787,16 +808,17 @@
      SourceCodeManager checkinClass:Array logMessage:'testing only'
     "
 
-    "Modified: 17.12.1995 / 16:02:37 / cg"
     "Modified: 20.12.1995 / 17:34:53 / stefan"
+    "Modified: 6.2.1996 / 17:57:52 / cg"
 !
 
-streamForClass:cls fileName:classFileName revision:revision directory:packageDir module:moduleDir cache:cacheIt
+streamForClass:cls fileName:fileName revision:revision directory:packageDir module:moduleDir cache:cacheIt
     "extract a source file and return an open readStream on it,
      or nil if the extract failed."
 
     |dir cachedSourceFilename temporaryFile file cachedFile cmd fullName revisionArg stream
-     checkoutDir checkoutName fullTempName fullCachedName tempdir cmdOut|
+     checkoutDir checkoutName fullTempName fullCachedName tempdir cmdOut
+     classFileName|
 
 
     "/ if not already existing, create a cache directory
@@ -807,22 +829,30 @@
     "/
 
     (dir := self sourceCacheDirectory) isNil ifTrue:[
-	'CVSMGR: no source cache directory' infoPrintNL.
-	^ nil
+        'CVSMGR: no source cache directory' infoPrintNL.
+        ^ nil
+    ].
+
+    classFileName := fileName.
+    (classFileName endsWith:',v') ifTrue:[
+        classFileName := classFileName copyWithoutLast:2.
+    ].
+    (classFileName endsWith:'.st') ifTrue:[
+        classFileName := classFileName copyWithoutLast:3.
     ].
 
     fullName := moduleDir , '/' , packageDir , '/' , classFileName , '.st'.
 
     (revision isNil or:[revision == #newest]) ifTrue:[
-	cachedSourceFilename := classFileName.
+        cachedSourceFilename := classFileName.
     ] ifFalse:[
-	cachedSourceFilename := classFileName , '_' , revision.
+        cachedSourceFilename := classFileName , '_' , revision.
     ].
 
     cachedFile := (dir construct:cachedSourceFilename) asFilename.
     cachedFile exists ifTrue:[
 "/        ('CVSMGR: found existing: ', cachedFile name) infoPrintNL.
-	^ cachedFile readStream
+        ^ cachedFile readStream
     ].
 
     "/
@@ -849,7 +879,7 @@
 
     cmdOut := Filename newTemporary.
     cmdOut exists ifTrue:[
-	cmdOut remove.
+        cmdOut remove.
     ].
 
     "/
@@ -859,25 +889,25 @@
     checkoutName :=  checkoutDir , '/' , classFileName , '.st'.
 
     (revision isNil or:[revision == #newest]) ifTrue:[
-	cachedSourceFilename := classFileName.
-	revisionArg := ''.
+        cachedSourceFilename := classFileName.
+        revisionArg := ''.
     ] ifFalse:[
-	cachedSourceFilename := classFileName , '_' , revision.
-	revisionArg := ' -r ' , revision.
+        cachedSourceFilename := classFileName , '_' , revision.
+        revisionArg := ' -r ' , revision.
     ].
 
     self activityNotification:'checking out source ' , checkoutName.
     cmd := 'cd ' , tempdir name , ';cvs -d ', CVSRoot, ' -l checkout' , revisionArg , ' ', checkoutName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
-	cmdOut remove.
-	tempdir recursiveRemove.
-	('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
-	^ nil.
+        'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
+        ^ nil.
     ].
 
     cmdOut remove.
@@ -885,24 +915,24 @@
     fullCachedName := CacheDirectoryName , '/' , cachedSourceFilename.
 
     cacheIt ifTrue:[
-	(OperatingSystem errorSignal catch:[
-	    fullTempName asFilename moveTo:fullCachedName
-	]) ifTrue:[
-	    ('CVSMGR: failed to rename ', fullTempName, ' to ', cachedSourceFilename) infoPrintNL.
-	    tempdir recursiveRemove.
-	    ^ nil
-	].
-	stream := cachedFile readStream
+        (OperatingSystem errorSignal catch:[
+            fullTempName asFilename moveTo:fullCachedName
+        ]) ifTrue:[
+            ('CVSMGR: failed to rename ', fullTempName, ' to ', cachedSourceFilename) infoPrintNL.
+            tempdir recursiveRemove.
+            ^ nil
+        ].
+        stream := cachedFile readStream
     ] ifFalse:[
-	stream := fullTempName asFilename readStream.
+        stream := fullTempName asFilename readStream.
     ].
 
     self releaseAndRemove:tempdir outputTo:nil. 
     ^ stream
 
     "Created: 4.11.1995 / 19:46:20 / cg"
-    "Modified: 17.12.1995 / 17:52:44 / cg"
     "Modified: 19.12.1995 / 16:15:26 / stefan"
+    "Modified: 6.2.1996 / 17:36:47 / cg"
 ! !
 
 !CVSSourceCodeManager class methodsFor:'source code administration'!
@@ -912,9 +942,15 @@
 
     fullName := moduleDir , '/' , packageDir , '/' , fileName.
     RemoteCVS ifFalse:[
-        ^ (CVSRoot , '/' , fullName , ',v') asFilename exists.
+        (fullName endsWith:',v') ifFalse:[
+            fullName := fullName , ',v'.
+        ].
+        ^ (CVSRoot , '/' , fullName) asFilename exists.
     ].
 
+    (fullName endsWith:',v') ifTrue:[
+        fullName := fullName copyWithoutLast:2.
+    ].
     ^ OperatingSystem executeCommand:'cvs -n -d ', CVSRoot, ' checkout ', fullName.
 
     "
@@ -926,7 +962,12 @@
      CVSSourceCodeManager 
         checkForExistingContainerInModule:'stx' 
         package:'libtool' 
-        container:'AboutBox.st' 
+        container:'AboutBox.st'  
+
+     CVSSourceCodeManager 
+        checkForExistingContainerInModule:'stx' 
+        package:'libtool' 
+        container:'AboutBox.st,v'     
 
      CVSSourceCodeManager 
         checkForExistingContainerInModule:'stx' 
@@ -936,7 +977,7 @@
 
     "Created: 9.12.1995 / 19:13:37 / cg"
     "Modified: 19.12.1995 / 14:15:43 / stefan"
-    "Modified: 26.1.1996 / 16:11:11 / cg"
+    "Modified: 6.2.1996 / 17:38:23 / cg"
 !
 
 checkForExistingModule:moduleDir
@@ -947,11 +988,16 @@
 
     ^ OperatingSystem executeCommand:'cvs -n -d ', CVSRoot, ' checkout ', moduleDir
 
-    "CVSSourceCodeManager checkForExistingModule:'stx'"
+    "
+     CVSSourceCodeManager checkForExistingModule:'stx'
+     CVSSourceCodeManager checkForExistingModule:'cg'  
+     CVSSourceCodeManager checkForExistingModule:'aeg' 
+     CVSSourceCodeManager checkForExistingModule:'foo'   
+    "
 
     "Created: 9.12.1995 / 19:13:37 / cg"
     "Modified: 19.12.1995 / 14:12:07 / stefan"
-    "Modified: 26.1.1996 / 16:09:58 / cg"
+    "Modified: 6.2.1996 / 17:39:02 / cg"
 !
 
 checkForExistingModule:moduleDir package:packageDir
@@ -965,14 +1011,23 @@
 
     ^ OperatingSystem executeCommand:'cvs -n -d ', CVSRoot, ' checkout ', fullName.
 
-    "CVSSourceCodeManager checkForExistingModule:'stx' package:'libbasic'"
+    "
+     CVSSourceCodeManager checkForExistingModule:'stx' package:'libbasic' 
+     CVSSourceCodeManager checkForExistingModule:'aeg' package:'libProgram'  
+     CVSSourceCodeManager checkForExistingModule:'foo' package:'libbasic' 
+     CVSSourceCodeManager checkForExistingModule:'foo' package:'bar'   
+     CVSSourceCodeManager checkForExistingModule:'cg' package:'private'   
+    "
 
     "Created: 9.12.1995 / 19:13:37 / cg"
     "Modified: 19.12.1995 / 14:18:42 / stefan"
-    "Modified: 26.1.1996 / 16:10:22 / cg"
+    "Modified: 6.2.1996 / 17:39:51 / cg"
 !
 
 createContainerFor:aClass inModule:moduleDir package:packageDir container:fileName
+    "create a container - this does an initial checkin
+     (i.e. cvs add & cvs commit)"
+
     |fullName tempdir checkoutName cmdOut cmd tempFile idx aStream whatHappened l newRevision
      changeLog entry newString startIdx|
 
@@ -984,7 +1039,7 @@
 
     cmdOut := Filename newTemporary.
     cmdOut exists ifTrue:[
-	cmdOut remove.
+        cmdOut remove.
     ].
 
     fullName := moduleDir , '/' , packageDir , '/' , fileName.
@@ -997,16 +1052,16 @@
 
     cmd := 'cd ' , tempdir name , ';cvs checkout -l ' , checkoutName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
+        'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
 
-	cmdOut remove.
-	tempdir recursiveRemove.
-	('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
+        ^ false.
     ].
 
     "/
@@ -1015,22 +1070,22 @@
     tempFile := (tempdir name , '/' , checkoutName , '/' , fileName) asFilename.
     aStream := tempFile writeStream.
     aStream isNil ifTrue:[
-	('CVSMGR: temporary fileout failed -> ', tempFile name) errorPrintNL.
-	^ false
+        ('CVSMGR: temporary fileout failed -> ', tempFile name) errorPrintNL.
+        ^ false
     ].
 
     Class fileOutErrorSignal handle:[:ex |
-	'CVSMGR: fileout failed' errorPrintNL.
-	aStream close.
-	^ false
+        'CVSMGR: fileout failed' errorPrintNL.
+        aStream close.
+        ^ false
     ] do:[
-	aClass fileOutOn:aStream withTimeStamp:false.
+        aClass fileOutOn:aStream withTimeStamp:false.
     ].
     aStream close.
 
     tempFile exists ifFalse:[
-	'SOURCEMGR: temporary fileout failed' errorPrintNL.
-	^ false
+        'SOURCEMGR: temporary fileout failed' errorPrintNL.
+        ^ false
     ].
 
     "/
@@ -1038,16 +1093,16 @@
     "/
     cmd := 'cd ' , tempdir name , '/' , checkoutName , ';cvs add ' , fileName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
+        'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
 
-	cmdOut remove.
-	tempdir recursiveRemove.
-	('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
+        ^ false.
     ].
 
     cmdOut remove.
@@ -1057,23 +1112,27 @@
     "/
     cmd := 'cd ' , tempdir name , ';cvs commit -m "intitial checkin" 2> ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	Verbose == true ifTrue:[
-	    'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
-	].
-	whatHappened := cmdOut contentsOfEntireFile asString.
-	self warn:'The following problem was reported by cvs:
+        Verbose == true ifTrue:[
+            'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
+        ].
+        cmdOut fileSize > 0 ifTrue:[
+            whatHappened := cmdOut contentsOfEntireFile asString.
+        ] ifFalse:[
+            whatHappened := '<< no message >>'
+        ].
+        self warn:'The following problem was reported by cvs:
 
 ' , whatHappened , '
 
 The class has NOT been checked into the repository.'.
 
        'CVSMGR: cannot checkin modified class source' errorPrintNL.
-	cmdOut remove.
-	tempdir recursiveRemove.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ^ false.
     ].
     whatHappened := cmdOut contentsOfEntireFile asString.
 
@@ -1086,25 +1145,25 @@
     "/ good - its in the CVS repository; now, we need the updated RCS header
     "/
     (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
-	'CVSMGR: oops - unexpected empty commit command output' errorPrintNL.
+        'CVSMGR: oops - unexpected empty commit command output' errorPrintNL.
     ] ifFalse:[
-	whatHappened := whatHappened asCollectionOfLines asStringCollection.
-	idx := whatHappened indexOfLineStartingWith:'initial revision:'.
-	idx ~~ 0 ifTrue:[
-	    startIdx := 18
-	] ifFalse:[
-	    idx := whatHappened indexOfLineStartingWith:'new revision:'.
-	    idx ~~ 0 ifTrue:[
-		'CVSMGR: oops - container existed' errorPrintNL.
-		startIdx := 14.
-	    ] ifFalse:[
-		'CVSMGR: oops - unexpected commit command output (no new-revision info)' errorPrintNL.
-	    ]
-	].
-	idx ~~ 0 ifTrue:[
-	    l := whatHappened at:idx.
-	    newRevision := (l copyFrom:startIdx to:(l indexOf:$; startingAt:startIdx)-1) withoutSpaces.
-	]
+        whatHappened := whatHappened asCollectionOfLines asStringCollection.
+        idx := whatHappened indexOfLineStartingWith:'initial revision:'.
+        idx ~~ 0 ifTrue:[
+            startIdx := 18
+        ] ifFalse:[
+            idx := whatHappened indexOfLineStartingWith:'new revision:'.
+            idx ~~ 0 ifTrue:[
+                'CVSMGR: oops - container existed' errorPrintNL.
+                startIdx := 14.
+            ] ifFalse:[
+                'CVSMGR: oops - unexpected commit command output (no new-revision info)' errorPrintNL.
+            ]
+        ].
+        idx ~~ 0 ifTrue:[
+            l := whatHappened at:idx.
+            newRevision := (l copyFrom:startIdx to:(l indexOf:$; startingAt:startIdx)-1) withoutSpaces.
+        ]
     ].
 
     "/
@@ -1116,29 +1175,29 @@
     "/
 
     newRevision notNil ifTrue:[
-	changeLog := self 
-			revisionLogOf:aClass 
-			fromRevision:newRevision 
-			toRevision:newRevision
-			fileName:fileName
-			directory:packageDir
-			module:moduleDir.
+        changeLog := self 
+                        revisionLogOf:aClass 
+                        fromRevision:newRevision 
+                        toRevision:newRevision
+                        fileName:fileName
+                        directory:packageDir
+                        module:moduleDir.
 
-	(changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
-	    'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
-	] ifFalse:[
-	    entry := (changeLog at:#revisions) first.
-	    newString := self revisionStringFromLog:changeLog entry:entry.
-	    aClass updateVersionMethodFor:newString.
-	    ('CVSMGR: updated revisionString to:',newString) errorPrintNL
-	]
+        (changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
+            'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
+        ] ifFalse:[
+            entry := (changeLog at:#revisions) first.
+            newString := self revisionStringFromLog:changeLog entry:entry.
+            aClass updateVersionMethodFor:newString.
+            ('CVSMGR: updated revisionString to:',newString) errorPrintNL
+        ]
     ].
 
     tempdir recursiveRemove.
     ^ true
 
     "Created: 9.12.1995 / 19:13:37 / cg"
-    "Modified: 17.12.1995 / 16:02:06 / cg"
+    "Modified: 6.2.1996 / 17:55:33 / cg"
 !
 
 createModule:moduleName
@@ -1277,169 +1336,174 @@
 
      The returned information is a structure (IdentityDictionary)
      filled with:
-	    #container          -> the RCS container file name 
-	    #filename           -> the actual source file name
-	    #newestRevision     -> the revisionString of the newest revision
-	    #numberOfRevisions  -> the number of revisions in the container
-	    #revisions          -> collection of per-revision info (see below)
+            #container          -> the RCS container file name 
+            #filename           -> the actual source file name
+            #newestRevision     -> the revisionString of the newest revision
+            #numberOfRevisions  -> the number of revisions in the container
+            #revisions          -> collection of per-revision info (see below)
 
-	    rev1 / rev2 specify from which revisions a logEntry is wanted:
-	     -If rev1 is nil, the first revision is the initial revision
-	      otherwise, the log starts with that revision.
-	     -If rev2 is nil, the last revision is the newest revision
-	      otherwise, the log ends with that revision.
+            rev1 / rev2 specify from which revisions a logEntry is wanted:
+             -If rev1 is nil, the first revision is the initial revision
+              otherwise, the log starts with that revision.
+             -If rev2 is nil, the last revision is the newest revision
+              otherwise, the log ends with that revision.
 
-	     -If both are nil, all logEntries are extracted.
-	     -If both are 0 (not nil), no logEntries are extracted (i.e. only the header).
+             -If both are nil, all logEntries are extracted.
+             -If both are 0 (not nil), no logEntries are extracted (i.e. only the header).
 
-	    per revision info consists of one record per revision:
+            per revision info consists of one record per revision:
 
-	      #revision              -> the revision string
-	      #author                -> who checked that revision into the repository
-	      #date                  -> when was it checked in
-	      #state                 -> the RCS state
-	      #numberOfChangedLines  -> the number of changed line w.r.t the previous
+              #revision              -> the revision string
+              #author                -> who checked that revision into the repository
+              #date                  -> when was it checked in
+              #state                 -> the RCS state
+              #numberOfChangedLines  -> the number of changed line w.r.t the previous
 
-	    revisions are ordered newest first 
-	    (i.e. the last entry is for the initial revision; the first for the most recent one)
-	"
+            revisions are ordered newest first 
+            (i.e. the last entry is for the initial revision; the first for the most recent one)
+        "
 
     |tempDir cmd fullName modulePath inStream inHeaderInfo atEnd line revArg revLine1 revLine2 idx
      info record revisionRecords s headerOnly|
 
     CVSRoot isNil ifTrue:[
-	'CVSMGR: CVSROOT not set' infoPrintNL.
-	^ nil
+        'CVSMGR: CVSROOT not set' infoPrintNL.
+        ^ nil
     ].
 
     modulePath :=  moduleDir , '/' , packageDir. 
     fullName :=  modulePath , '/' , classFileName.
     tempDir := self createTempDirectory:nil forModule:nil.
     [
-	self createEntryFor:fullName 
-	     in:(tempDir construct:modulePath) 
-	     revision:'1.1' 
-	     date:'dummy' 
-	     special:''
-	     overwrite:false.
+        self createEntryFor:fullName 
+             in:(tempDir construct:modulePath) 
+             revision:'1.1' 
+             date:'dummy' 
+             special:''
+             overwrite:false.
 
-	revArg := ''.
-	headerOnly := false.
-	(rev1 notNil or:[rev2 notNil]) ifTrue:[
-	    (rev1 == 0 and:[rev2 == 0]) ifTrue:[
-		revArg := '-h'.
-		headerOnly := true.
-	    ] ifFalse:[
-		revArg := '-r'.
-		rev1 notNil ifTrue:[
-		    revArg := revArg , rev1
-		].
-		revArg := revArg , ':'.
-		rev2 notNil ifTrue:[
-		    revArg := revArg , rev2
-		].
-	    ]
-	].
+        revArg := ''.
+        headerOnly := false.
+        (rev1 notNil or:[rev2 notNil]) ifTrue:[
+            (rev1 == 0 and:[rev2 == 0]) ifTrue:[
+                revArg := '-h'.
+                headerOnly := true.
+            ] ifFalse:[
+                revArg := '-r'.
+                rev1 notNil ifTrue:[
+                    revArg := revArg , rev1
+                ].
+                revArg := revArg , ':'.
+                rev2 notNil ifTrue:[
+                    revArg := revArg , rev2
+                ].
+            ]
+        ].
 
-	self activityNotification:'reading log'.
-	cmd := 'cd ', tempDir name, '; cvs -d ', CVSRoot, ' log ' , revArg , ' ' , fullName.
+        self activityNotification:'reading log'.
+        cmd := 'cd ', tempDir name, '; cvs -d ', CVSRoot, ' log ' , revArg , ' ' , fullName.
     "/ cmd printNL.
-	inStream := PipeStream readingFrom:cmd.
-	inStream isNil ifTrue:[
-	    ('CVSMGR: cannot open pipe to cvs log ', fullName) infoPrintNL.
-	    ^ nil
-	].
+        inStream := PipeStream readingFrom:cmd.
+        inStream isNil ifTrue:[
+            ('CVSMGR: cannot open pipe to cvs log ', fullName) infoPrintNL.
+            ^ nil
+        ].
 
-	"/
-	"/ read the commands pipe output and extract the container info
-	"/
-	info := IdentityDictionary new.
-	inHeaderInfo := true.
-	[inHeaderInfo and:[inStream atEnd not]] whileTrue:[
-	    line:= inStream nextLine.
-	    line notNil ifTrue:[
-		|gotIt|
+        "/
+        "/ read the commands pipe output and extract the container info
+        "/
+        info := IdentityDictionary new.
+        inHeaderInfo := true.
+        [inHeaderInfo and:[inStream atEnd not]] whileTrue:[
+            line:= inStream nextLine.
+            line notNil ifTrue:[
+                |gotIt|
 
-		gotIt := false.
-		#('RCS file:' #container
-		  'Working file:' #filename
-		  'head:' #newestRevision
-		  'total revisions:' #numberOfRevisions
-		 ) pairWiseDo:[:word :key |
-		    gotIt ifFalse:[
-			s := line restAfter:word withoutSeparators:true.
-			s notNil ifTrue:[info at:key put:s. gotIt := true].                        
-		    ]
-		].
-		gotIt ifFalse:[
-		    (line startsWith:'description:') ifTrue:[inHeaderInfo := false].
-		]
-	    ]
-	].
-	inStream nextLine. "/ skip separating line after description.
+                gotIt := false.
+                #('RCS file:' #container
+                  'Working file:' #filename
+                  'head:' #newestRevision
+                  'total revisions:' #numberOfRevisions
+                 ) pairWiseDo:[:word :key |
+                    gotIt ifFalse:[
+                        s := line restAfter:word withoutSeparators:true.
+                        s notNil ifTrue:[info at:key put:s. gotIt := true].                        
+                    ]
+                ].
+                gotIt ifFalse:[
+                    (line startsWith:'description:') ifTrue:[inHeaderInfo := false].
+                ]
+            ]
+        ].
+        inStream nextLine. "/ skip separating line after description.
 
-	"/ strip selected revisions from the total-revisions entry
-	s := info at:#numberOfRevisions.
-	(idx := s indexOf:$;) ~~ 0 ifTrue:[
-	    info at:#numberOfRevisions put:(Integer readFrom:(s copyTo:idx - 1))
-	].
+        info isEmpty ifTrue:[
+            ('CVSMGR: no log for ', fullName) infoPrintNL.
+            ^ nil
+        ].
 
-	headerOnly ifFalse:[
-	    "/
-	    "/ continue to read the commands pipe output 
-	    "/ and extract revision info records
-	    "/
-	    revisionRecords := OrderedCollection new:(info at:#numberOfRevisions).
-	    info at:#revisions put:revisionRecords.
+        "/ strip selected revisions from the total-revisions entry
+        s := info at:#numberOfRevisions.
+        (idx := s indexOf:$;) ~~ 0 ifTrue:[
+            info at:#numberOfRevisions put:(Integer readFrom:(s copyTo:idx - 1))
+        ].
+
+        headerOnly ifFalse:[
+            "/
+            "/ continue to read the commands pipe output 
+            "/ and extract revision info records
+            "/
+            revisionRecords := OrderedCollection new:(info at:#numberOfRevisions).
+            info at:#revisions put:revisionRecords.
 
-	    atEnd := false.
-	    [atEnd or:[inStream atEnd]] whileFalse:[
-		revLine1 := inStream nextLine.
-		[revLine1 notNil and:[(revLine1 startsWith:'revision ') not]]
-		    whileTrue:[revLine1 := inStream nextLine.].
-		revLine2 := inStream nextLine.
-		(revLine1 notNil and:[revLine2 notNil]) ifTrue:[
-		    record := IdentityDictionary new.
-		    record at:#revision put:(revLine1 asCollectionOfWords at:2).
-		    "/ decompose date/author/state etc.
-		    (revLine2 asCollectionOfSubstringsSeparatedBy:$;) do:[:info |
-			|subEntry|
-			subEntry := info withoutSeparators.
-			#('date:' #date
-			  'author:' #author 
-			  'state:' #state 
-			  'lines:' #numberOfChangedLines
-			 ) pairWiseDo:[:word :key |
-			    s := subEntry restAfter:word withoutSeparators:true.
-			    s notNil ifTrue:[record at:key put:s.].                        
-			].
-		    ].
+            atEnd := false.
+            [atEnd or:[inStream atEnd]] whileFalse:[
+                revLine1 := inStream nextLine.
+                [revLine1 notNil and:[(revLine1 startsWith:'revision ') not]]
+                    whileTrue:[revLine1 := inStream nextLine.].
+                revLine2 := inStream nextLine.
+                (revLine1 notNil and:[revLine2 notNil]) ifTrue:[
+                    record := IdentityDictionary new.
+                    record at:#revision put:(revLine1 asCollectionOfWords at:2).
+                    "/ decompose date/author/state etc.
+                    (revLine2 asCollectionOfSubstringsSeparatedBy:$;) do:[:info |
+                        |subEntry|
+                        subEntry := info withoutSeparators.
+                        #('date:' #date
+                          'author:' #author 
+                          'state:' #state 
+                          'lines:' #numberOfChangedLines
+                         ) pairWiseDo:[:word :key |
+                            s := subEntry restAfter:word withoutSeparators:true.
+                            s notNil ifTrue:[record at:key put:s.].                        
+                        ].
+                    ].
 
-		    s := nil.
-		    line := inStream nextLine.
-		    [atEnd or:[line isNil or:[line startsWith:'--------']]] whileFalse:[
-			(line startsWith:'==========') ifTrue:[
-			    atEnd := true.
-			] ifFalse:[
-			    (line withoutSpaces = '.') ifTrue:[
-				line := '*** empty log message ***'
-			    ].
-			    s isNil ifTrue:[
-				s := line
-			    ] ifFalse:[
-				s := s , Character cr asString , line.
-			    ].
-			    line := inStream nextLine.
-			]
-		    ].
-		    record at:#logMessage put:s.
-		    revisionRecords add:record.
-		]
-	    ].
-	].
-	inStream close.
+                    s := nil.
+                    line := inStream nextLine.
+                    [atEnd or:[line isNil or:[line startsWith:'--------']]] whileFalse:[
+                        (line startsWith:'==========') ifTrue:[
+                            atEnd := true.
+                        ] ifFalse:[
+                            (line withoutSpaces = '.') ifTrue:[
+                                line := '*** empty log message ***'
+                            ].
+                            s isNil ifTrue:[
+                                s := line
+                            ] ifFalse:[
+                                s := s , Character cr asString , line.
+                            ].
+                            line := inStream nextLine.
+                        ]
+                    ].
+                    record at:#logMessage put:s.
+                    revisionRecords add:record.
+                ]
+            ].
+        ].
+        inStream close.
     ] valueNowOrOnUnwindDo:[
-	tempDir recursiveRemove
+        tempDir recursiveRemove
     ].
     ^ info
 
@@ -1453,8 +1517,8 @@
     "
 
     "Created: 16.11.1995 / 13:25:30 / cg"
-    "Modified: 16.12.1995 / 18:53:02 / cg"
     "Modified: 20.12.1995 / 11:06:11 / stefan"
+    "Modified: 6.2.1996 / 16:22:43 / cg"
 !
 
 writeHistoryLogSince:timeGoal filterSTSources:filter filterUser:userFilter to:aStream
@@ -1537,6 +1601,6 @@
 !CVSSourceCodeManager class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic3/Attic/CVSSCMgr.st,v 1.77 1996-01-26 15:12:01 ah Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic3/Attic/CVSSCMgr.st,v 1.78 1996-02-06 20:28:12 cg Exp $'
 ! !
 CVSSourceCodeManager initialize!
--- a/CVSSourceCodeManager.st	Fri Feb 02 17:25:01 1996 +0100
+++ b/CVSSourceCodeManager.st	Tue Feb 06 21:28:12 1996 +0100
@@ -321,10 +321,20 @@
     "/ do not make the string below into one string;
     "/ RCS would expand it into a wrong rev-string
 
+    |nm|
+
+    nm := fileName.
+    (nm endsWith:',v') ifTrue:[
+        nm := nm copyWithoutLast:2
+    ].
+    (nm endsWith:'.st') ifFalse:[
+        nm := nm , '.st'
+    ].
+
     ^ '$' , 'Header: ' , CVSRoot , '/' , moduleDir , '/' , packageDir , '/' , fileName , ',v $'
 
     "Created: 9.12.1995 / 21:28:11 / cg"
-    "Modified: 12.12.1995 / 19:41:11 / cg"
+    "Modified: 6.2.1996 / 16:43:53 / cg"
 !
 
 releaseAndRemove:tempdir outputTo:outputFilename
@@ -422,32 +432,32 @@
     className := cls name.
 
     merge ifTrue:[
-	revision := cls revision.
-	revision isNil ifTrue:[ 
-	    ('CVSMGR: class ' , className, ' has no revision string') errorPrintNL.
-	    (self confirm:('class ' , className, ' has no (usable) revision string.\\check in as newest ?') withCRs)
-	    ifFalse:[
-		^ false.
-	    ].
-	].
-	(binRevision := cls binaryRevision) notNil ifTrue:[
-	    revision ~= binRevision ifTrue:[
-		('CVSMGR: class ' , className , ' is based upon ' , binRevision , ' but has revision ' , revision) infoPrintNL
-	    ]
-	]
+        revision := cls revision.
+        revision isNil ifTrue:[ 
+            ('CVSMGR: class ' , className, ' has no revision string') errorPrintNL.
+            (self confirm:('class ' , className, ' has no (usable) revision string.\\check in as newest ?') withCRs)
+            ifFalse:[
+                ^ false.
+            ].
+        ].
+        (binRevision := cls binaryRevision) notNil ifTrue:[
+            revision ~= binRevision ifTrue:[
+                ('CVSMGR: class ' , className , ' is based upon ' , binRevision , ' but has revision ' , revision) infoPrintNL
+            ]
+        ]
     ].
     revision isNil ifTrue:[
-	revision := '1.0'
+        revision := '1.0'
     ].
 
     logMsg := logMessage.
     (logMsg isNil or:[logMsg isEmpty]) ifTrue:[
-	logMsg := 'checkin from browser'.
+        logMsg := 'checkin from browser'.
     ].
 
     cmdOut := Filename newTemporary.
     cmdOut exists ifTrue:[
-	cmdOut remove.
+        cmdOut remove.
     ].
 
     "/
@@ -475,11 +485,11 @@
     time := time addSeconds:(time utcOffset).
 
     self createEntryFor:checkoutName 
-	 in:(tempdir construct:modulePath) 
-	 revision:revision
-	 date:(self cvsTimeString:time)
-	 special:''
-	 overwrite:true.
+         in:(tempdir construct:modulePath) 
+         revision:revision
+         date:(self cvsTimeString:time)
+         special:''
+         overwrite:true.
 
     "/
     "/ copy-over our current version
@@ -488,9 +498,9 @@
 "/ ('move over: ' , cmd) infoPrintNL.
     (OperatingSystem executeCommand:cmd) ifFalse:[
 "/        'failed: ' errorPrint. cmd errorPrintNL.
-	tempdir recursiveRemove.
-	'CVSMGR: cannot copy-over filedOut class source' errorPrintNL.
-	^ false.
+        tempdir recursiveRemove.
+        'CVSMGR: cannot copy-over filedOut class source' errorPrintNL.
+        ^ false.
     ].
 
 merge ifTrue:[
@@ -502,15 +512,15 @@
 
     cmd := 'cd ' , tempdir name , ';cvs -d ', CVSRoot, ' update ' , checkoutName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
-	tempdir recursiveRemove.
-	cmdOut remove.
-	'CVSMGR: cannot merge current source with repository version' errorPrintNL.
-	^ false.
+        'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
+        tempdir recursiveRemove.
+        cmdOut remove.
+        'CVSMGR: cannot merge current source with repository version' errorPrintNL.
+        ^ false.
     ].
 
     "/
@@ -520,26 +530,29 @@
     "/   C xxx   -> a conflict occured and the differences have been merged into the source
     "/              needs special action
     "/
-    whatHappened := cmdOut contentsOfEntireFile asString.
+    cmdOut fileSize > 0 ifTrue:[
+        whatHappened := cmdOut contentsOfEntireFile asString.
+    ].
     cmdOut remove.
 
+    (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
+        "/
+        "/ no change
+        "/
+        tempdir recursiveRemove.
+        Transcript showCr:'no change in ' , className , ' (repository unchanged)'.
+        self information:'nothing changed in ' , className.
+        ^ true
+    ].
+
     Verbose == true ifTrue:[
-	('CVSMGR: result is: ' , whatHappened) infoPrintNL.
-    ].
-    (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
-	"/
-	"/ no change
-	"/
-	tempdir recursiveRemove.
-	Transcript showCr:'no change in ' , className , ' (repository unchanged)'.
-	self information:'nothing changed in ' , className.
-	^ true
+        ('CVSMGR: result is: ' , whatHappened) infoPrintNL.
     ].
 
     revision isNil ifTrue:[
-	changeLog := self revisionLogOf:cls.
+        changeLog := self revisionLogOf:cls.
     ] ifFalse:[
-	changeLog := self revisionLogOf:cls fromRevision:(self revisionAfter:revision) toRevision:nil.
+        changeLog := self revisionLogOf:cls fromRevision:(self revisionAfter:revision) toRevision:nil.
     ].
     s := WriteStream on:String new.
     self writeRevisionLogMessagesFrom:changeLog withHeader:false to:s.
@@ -547,42 +560,42 @@
     didMerge := false.
 
     (whatHappened startsWith:'M ') ifTrue:[
-	"/
-	"/ merged in changes
-	"/
-	(changeLog at:#revisions) isEmpty ifTrue:[
-	    "/
-	    "/ pretty good - nothing has changed in the meanwhile
-	    "/
-	    Transcript showCr:'checking in ' , className , ' ...'
-	] ifFalse:[
-	    "/
-	    "/ someone else has changed things in the meanwhile, but there is no conflict
-	    "/ and version have been merged.
-	    "/
-	    didMerge := true.
-	    changesAsLogged := changesAsLogged asCollectionOfLines.
+        "/
+        "/ merged in changes
+        "/
+        (changeLog at:#revisions) isEmpty ifTrue:[
+            "/
+            "/ pretty good - nothing has changed in the meanwhile
+            "/
+            Transcript showCr:'checking in ' , className , ' ...'
+        ] ifFalse:[
+            "/
+            "/ someone else has changed things in the meanwhile, but there is no conflict
+            "/ and version have been merged.
+            "/
+            didMerge := true.
+            changesAsLogged := changesAsLogged asCollectionOfLines.
 
-	    s := WriteStream on:String new.
-	    cls fileOutOn:s withTimeStamp:false.
-	    mySource := s contents asString.
-	    mergedSource := (tempdir name , '/' , checkoutName) asFilename readStream contents asString.
+            s := WriteStream on:String new.
+            cls fileOutOn:s withTimeStamp:false.
+            mySource := s contents asString.
+            mergedSource := (tempdir name , '/' , checkoutName) asFilename readStream contents asString.
 
-	    mySource = mergedSource ifTrue:[
-		msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
+            mySource = mergedSource ifTrue:[
+                msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
 
 I have merged your version with the newest repository version, 
 and found no differences between the result and your current version
 (i.e. your version seemed up-to-date).'.
 
-		self checkinTroubleDialog:'Merging versions'
-			       message:msg 
-			       log:changesAsLogged
-			       abortable:false 
-			       option:nil.
-		didMerge := false.
-	    ] ifFalse:[
-		msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
+                self checkinTroubleDialog:'Merging versions'
+                               message:msg 
+                               log:changesAsLogged
+                               abortable:false 
+                               option:nil.
+                didMerge := false.
+            ] ifFalse:[
+                msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
 
 If you continue, your new changes (based upon rev. ' , revision printString , ') will be MERGED
 into the newest revision. This will combine the other version with your changes
@@ -597,25 +610,25 @@
 
 Continue ?'.
 
-		answer := self checkinTroubleDialog:'Merging versions'
-			       message:msg 
-			       log:changesAsLogged
-			       abortable:true
-			       option:'stop - see first'.
-		answer ~~ true ifTrue:[
-		    answer == #option ifTrue:[
-			DiffTextView 
-			    openOn:mySource
-			    label:'current version'
-			    and:mergedSource
-			    label:'merged version'.
+                answer := self checkinTroubleDialog:'Merging versions'
+                               message:msg 
+                               log:changesAsLogged
+                               abortable:true
+                               option:'stop - see first'.
+                answer ~~ true ifTrue:[
+                    answer == #option ifTrue:[
+                        DiffTextView 
+                            openOn:mySource
+                            label:'current version'
+                            and:mergedSource
+                            label:'merged version'.
                             
-		    ].
-		    Transcript showCr:'checkin aborted - (no merge; repository unchanged)'.
-		    tempdir recursiveRemove.
-		    ^ false.
-		].
-	    ].
+                    ].
+                    Transcript showCr:'checkin aborted - (no merge; repository unchanged)'.
+                    tempdir recursiveRemove.
+                    ^ false.
+                ].
+            ].
 
 "/                changesAsLogged := (changesAsLogged asStringCollection collect:[:line | line withTabsExpanded]) asString.
 "/                msg := 'The source of ' , className , ' has been changed in the meanwhile as follows:
@@ -637,18 +650,18 @@
 "/                    tempdir recursiveRemove.
 "/                    ^ false.
 "/                ].
-	    Transcript showCr:'checking in ' , className , ' (merged other changes) ...'
-	]
+            Transcript showCr:'checking in ' , className , ' (merged other changes) ...'
+        ]
     ] ifFalse:[
-	(whatHappened startsWith:'C ') ifTrue:[
-	    "/
-	    "/ conflict; someone else checked in something in the meanwhile,
-	    "/ and there is a conflict between this version and the checked in version.
-	    "/
+        (whatHappened startsWith:'C ') ifTrue:[
+            "/
+            "/ conflict; someone else checked in something in the meanwhile,
+            "/ and there is a conflict between this version and the checked in version.
+            "/
 
-	    changesAsLogged := changesAsLogged asCollectionOfLines.
+            changesAsLogged := changesAsLogged asCollectionOfLines.
 
-	    msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
+            msg := 'The source of ' , className , ' has been changed in the meanwhile as listed below.
 
 Your new changes (based upon rev. ' , revision printString , ') CONFLICT with those changes.
 
@@ -656,44 +669,44 @@
 and change your methods avoiding conflicts. The checkin again.
 '.
 
-	    (self checkinTroubleDialog:'Version conflict'
-		 message:msg 
-		 log:changesAsLogged
-		 abortable:false
-		 option:'show conflicts') == #option ifTrue:[
-		"/
-		"/ for now, show the conflicts in a dump view
-		"/ Later, there will be a 3-way DiffTextView ...
-		"/
-		Diff3TextView
-		    openOnMergedText:(tempdir name , '/' , checkoutName) asFilename readStream contents 
-		    label:'original' label:'repository' label:'your version'. 
+            (self checkinTroubleDialog:'Version conflict'
+                 message:msg 
+                 log:changesAsLogged
+                 abortable:false
+                 option:'show conflicts') == #option ifTrue:[
+                "/
+                "/ for now, show the conflicts in a dump view
+                "/ Later, there will be a 3-way DiffTextView ...
+                "/
+                Diff3TextView
+                    openOnMergedText:(tempdir name , '/' , checkoutName) asFilename readStream contents 
+                    label:'original' label:'repository' label:'your version'. 
 "/                TextView 
 "/                    openWith:(tempdir name , '/' , checkoutName) asFilename readStream contents
 "/                    title:'conflicts'.
-	    ].
+            ].
 
 "/                changesAsLogged := (changesAsLogged asCollectionOfLines asStringCollection collect:[:line | line withTabsExpanded]) asString.
 "/                self warn:'The source of ' , className , ' has been changed in the meanwhile as follows:
 "/' , changesAsLogged , '
 "/Your new changes (based upon rev. ' , revision , ') CONFLICT with those changes - please fix.'.
 
-	    'CVSMGR: cannot (for now) checkin; conflicts found' errorPrintNL.
-	    Transcript showCr:'checkin of ' , className , ' aborted (conflicting changes; repository unchanged)'.
-	    tempdir recursiveRemove.
-	    ^ false.
-	] ifFalse:[
-	    "/
-	    "/ unexpected
-	    "/
-	    self warn:'unexpected message from CVS:
+            'CVSMGR: cannot (for now) checkin; conflicts found' errorPrintNL.
+            Transcript showCr:'checkin of ' , className , ' aborted (conflicting changes; repository unchanged)'.
+            tempdir recursiveRemove.
+            ^ false.
+        ] ifFalse:[
+            "/
+            "/ unexpected
+            "/
+            self warn:'unexpected message from CVS:
 ' , whatHappened , '
 
 No checkin performed.'.
-	    Transcript showCr:'*** cannot checkin ' , className , ' (unexpected CVS response; repository unchanged)'.
-	    tempdir recursiveRemove.
-	    ^ false.
-	]
+            Transcript showCr:'*** cannot checkin ' , className , ' (unexpected CVS response; repository unchanged)'.
+            tempdir recursiveRemove.
+            ^ false.
+        ]
     ].
 ].
 
@@ -705,25 +718,33 @@
     logMsg := logMsg replChar:$"  withString:'\"'.
     cmd := 'cd ' , tempdir name , ';cvs -d ', CVSRoot, ' commit -m "', logMsg ,'" ' , checkoutName, ' 2> ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	Verbose == true ifTrue:[
-	    'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
-	].
-	whatHappened := cmdOut contentsOfEntireFile asString.
-	self warn:'The following problem was reported by cvs:
+        Verbose == true ifTrue:[
+            'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
+        ].
+        cmdOut fileSize > 0 ifTrue:[
+            whatHappened := cmdOut contentsOfEntireFile asString.
+        ] ifFalse:[
+            whatHappened := '<< no message >>'
+        ].
+        self warn:'The following problem was reported by cvs:
 
 ' , whatHappened , '
 
 The class has NOT been checked into the repository.'.
 
        'CVSMGR: cannot checkin modified class source' errorPrintNL.
-	cmdOut remove.
-	tempdir recursiveRemove.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ^ false.
     ].
-    whatHappened := cmdOut contentsOfEntireFile asString.
+    cmdOut fileSize > 0 ifTrue:[
+        whatHappened := cmdOut contentsOfEntireFile asString.
+    ] ifFalse:[
+        whatHappened := nil
+    ].
 
     tempdir recursiveRemove.
     cmdOut remove.
@@ -733,16 +754,16 @@
     "/
 
     (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
-	'CVSMGR: oops - unexpected empty checkin command output' errorPrintNL.
+        'CVSMGR: oops - unexpected empty checkin command output' errorPrintNL.
     ] ifFalse:[
-	whatHappened := whatHappened asCollectionOfLines asStringCollection.
-	idx := whatHappened indexOfLineStartingWith:'new revision:'.
-	idx == 0 ifTrue:[
-	    'CVSMGR: oops - unexpected checkin command output (no new-revision info)' errorPrintNL.
-	] ifFalse:[
-	    l := whatHappened at:idx.
-	    newRevision := (l copyFrom:14 to:(l indexOf:$; startingAt:14)-1) withoutSpaces.
-	]
+        whatHappened := whatHappened asCollectionOfLines asStringCollection.
+        idx := whatHappened indexOfLineStartingWith:'new revision:'.
+        idx == 0 ifTrue:[
+            'CVSMGR: oops - unexpected checkin command output (no new-revision info)' errorPrintNL.
+        ] ifFalse:[
+            l := whatHappened at:idx.
+            newRevision := (l copyFrom:14 to:(l indexOf:$; startingAt:14)-1) withoutSpaces.
+        ]
     ].
 
     "/
@@ -760,24 +781,24 @@
     "/    If we later checkin again, the new checkin will be again based on the current revision
     "/
     newRevision notNil ifTrue:[
-	didMerge ifFalse:[
-	    self activityNotification:'fetch revision number'.
+        didMerge ifFalse:[
+            self activityNotification:'fetch revision number'.
 
-	    changeLog := self revisionLogOf:cls fromRevision:newRevision toRevision:newRevision.
-	    (changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
-		'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
-	    ] ifFalse:[
-		entry := (changeLog at:#revisions) first.
-		newString := self revisionStringFromLog:changeLog entry:entry.
-		cls updateVersionMethodFor:newString.
-		cls revision ~= newRevision ifTrue:[
-		    'CVSMGR: oops - failed to update revisionString' errorPrintNL
-		]
-	    ]
-	] ifTrue:[
-	    newString := self updatedRevisionStringOf:cls forRevision:nil with:cls revisionString.
-	    cls updateVersionMethodFor:newString.
-	].
+            changeLog := self revisionLogOf:cls fromRevision:newRevision toRevision:newRevision.
+            (changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
+                'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
+            ] ifFalse:[
+                entry := (changeLog at:#revisions) first.
+                newString := self revisionStringFromLog:changeLog entry:entry.
+                cls updateVersionMethodFor:newString.
+                cls revision ~= newRevision ifTrue:[
+                    'CVSMGR: oops - failed to update revisionString' errorPrintNL
+                ]
+            ]
+        ] ifTrue:[
+            newString := self updatedRevisionStringOf:cls forRevision:nil with:cls revisionString.
+            cls updateVersionMethodFor:newString.
+        ].
     ].
 
     Class addChangeRecordForClassCheckIn:cls.
@@ -787,16 +808,17 @@
      SourceCodeManager checkinClass:Array logMessage:'testing only'
     "
 
-    "Modified: 17.12.1995 / 16:02:37 / cg"
     "Modified: 20.12.1995 / 17:34:53 / stefan"
+    "Modified: 6.2.1996 / 17:57:52 / cg"
 !
 
-streamForClass:cls fileName:classFileName revision:revision directory:packageDir module:moduleDir cache:cacheIt
+streamForClass:cls fileName:fileName revision:revision directory:packageDir module:moduleDir cache:cacheIt
     "extract a source file and return an open readStream on it,
      or nil if the extract failed."
 
     |dir cachedSourceFilename temporaryFile file cachedFile cmd fullName revisionArg stream
-     checkoutDir checkoutName fullTempName fullCachedName tempdir cmdOut|
+     checkoutDir checkoutName fullTempName fullCachedName tempdir cmdOut
+     classFileName|
 
 
     "/ if not already existing, create a cache directory
@@ -807,22 +829,30 @@
     "/
 
     (dir := self sourceCacheDirectory) isNil ifTrue:[
-	'CVSMGR: no source cache directory' infoPrintNL.
-	^ nil
+        'CVSMGR: no source cache directory' infoPrintNL.
+        ^ nil
+    ].
+
+    classFileName := fileName.
+    (classFileName endsWith:',v') ifTrue:[
+        classFileName := classFileName copyWithoutLast:2.
+    ].
+    (classFileName endsWith:'.st') ifTrue:[
+        classFileName := classFileName copyWithoutLast:3.
     ].
 
     fullName := moduleDir , '/' , packageDir , '/' , classFileName , '.st'.
 
     (revision isNil or:[revision == #newest]) ifTrue:[
-	cachedSourceFilename := classFileName.
+        cachedSourceFilename := classFileName.
     ] ifFalse:[
-	cachedSourceFilename := classFileName , '_' , revision.
+        cachedSourceFilename := classFileName , '_' , revision.
     ].
 
     cachedFile := (dir construct:cachedSourceFilename) asFilename.
     cachedFile exists ifTrue:[
 "/        ('CVSMGR: found existing: ', cachedFile name) infoPrintNL.
-	^ cachedFile readStream
+        ^ cachedFile readStream
     ].
 
     "/
@@ -849,7 +879,7 @@
 
     cmdOut := Filename newTemporary.
     cmdOut exists ifTrue:[
-	cmdOut remove.
+        cmdOut remove.
     ].
 
     "/
@@ -859,25 +889,25 @@
     checkoutName :=  checkoutDir , '/' , classFileName , '.st'.
 
     (revision isNil or:[revision == #newest]) ifTrue:[
-	cachedSourceFilename := classFileName.
-	revisionArg := ''.
+        cachedSourceFilename := classFileName.
+        revisionArg := ''.
     ] ifFalse:[
-	cachedSourceFilename := classFileName , '_' , revision.
-	revisionArg := ' -r ' , revision.
+        cachedSourceFilename := classFileName , '_' , revision.
+        revisionArg := ' -r ' , revision.
     ].
 
     self activityNotification:'checking out source ' , checkoutName.
     cmd := 'cd ' , tempdir name , ';cvs -d ', CVSRoot, ' -l checkout' , revisionArg , ' ', checkoutName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
-	cmdOut remove.
-	tempdir recursiveRemove.
-	('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
-	^ nil.
+        'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
+        ^ nil.
     ].
 
     cmdOut remove.
@@ -885,24 +915,24 @@
     fullCachedName := CacheDirectoryName , '/' , cachedSourceFilename.
 
     cacheIt ifTrue:[
-	(OperatingSystem errorSignal catch:[
-	    fullTempName asFilename moveTo:fullCachedName
-	]) ifTrue:[
-	    ('CVSMGR: failed to rename ', fullTempName, ' to ', cachedSourceFilename) infoPrintNL.
-	    tempdir recursiveRemove.
-	    ^ nil
-	].
-	stream := cachedFile readStream
+        (OperatingSystem errorSignal catch:[
+            fullTempName asFilename moveTo:fullCachedName
+        ]) ifTrue:[
+            ('CVSMGR: failed to rename ', fullTempName, ' to ', cachedSourceFilename) infoPrintNL.
+            tempdir recursiveRemove.
+            ^ nil
+        ].
+        stream := cachedFile readStream
     ] ifFalse:[
-	stream := fullTempName asFilename readStream.
+        stream := fullTempName asFilename readStream.
     ].
 
     self releaseAndRemove:tempdir outputTo:nil. 
     ^ stream
 
     "Created: 4.11.1995 / 19:46:20 / cg"
-    "Modified: 17.12.1995 / 17:52:44 / cg"
     "Modified: 19.12.1995 / 16:15:26 / stefan"
+    "Modified: 6.2.1996 / 17:36:47 / cg"
 ! !
 
 !CVSSourceCodeManager class methodsFor:'source code administration'!
@@ -912,9 +942,15 @@
 
     fullName := moduleDir , '/' , packageDir , '/' , fileName.
     RemoteCVS ifFalse:[
-        ^ (CVSRoot , '/' , fullName , ',v') asFilename exists.
+        (fullName endsWith:',v') ifFalse:[
+            fullName := fullName , ',v'.
+        ].
+        ^ (CVSRoot , '/' , fullName) asFilename exists.
     ].
 
+    (fullName endsWith:',v') ifTrue:[
+        fullName := fullName copyWithoutLast:2.
+    ].
     ^ OperatingSystem executeCommand:'cvs -n -d ', CVSRoot, ' checkout ', fullName.
 
     "
@@ -926,7 +962,12 @@
      CVSSourceCodeManager 
         checkForExistingContainerInModule:'stx' 
         package:'libtool' 
-        container:'AboutBox.st' 
+        container:'AboutBox.st'  
+
+     CVSSourceCodeManager 
+        checkForExistingContainerInModule:'stx' 
+        package:'libtool' 
+        container:'AboutBox.st,v'     
 
      CVSSourceCodeManager 
         checkForExistingContainerInModule:'stx' 
@@ -936,7 +977,7 @@
 
     "Created: 9.12.1995 / 19:13:37 / cg"
     "Modified: 19.12.1995 / 14:15:43 / stefan"
-    "Modified: 26.1.1996 / 16:11:11 / cg"
+    "Modified: 6.2.1996 / 17:38:23 / cg"
 !
 
 checkForExistingModule:moduleDir
@@ -947,11 +988,16 @@
 
     ^ OperatingSystem executeCommand:'cvs -n -d ', CVSRoot, ' checkout ', moduleDir
 
-    "CVSSourceCodeManager checkForExistingModule:'stx'"
+    "
+     CVSSourceCodeManager checkForExistingModule:'stx'
+     CVSSourceCodeManager checkForExistingModule:'cg'  
+     CVSSourceCodeManager checkForExistingModule:'aeg' 
+     CVSSourceCodeManager checkForExistingModule:'foo'   
+    "
 
     "Created: 9.12.1995 / 19:13:37 / cg"
     "Modified: 19.12.1995 / 14:12:07 / stefan"
-    "Modified: 26.1.1996 / 16:09:58 / cg"
+    "Modified: 6.2.1996 / 17:39:02 / cg"
 !
 
 checkForExistingModule:moduleDir package:packageDir
@@ -965,14 +1011,23 @@
 
     ^ OperatingSystem executeCommand:'cvs -n -d ', CVSRoot, ' checkout ', fullName.
 
-    "CVSSourceCodeManager checkForExistingModule:'stx' package:'libbasic'"
+    "
+     CVSSourceCodeManager checkForExistingModule:'stx' package:'libbasic' 
+     CVSSourceCodeManager checkForExistingModule:'aeg' package:'libProgram'  
+     CVSSourceCodeManager checkForExistingModule:'foo' package:'libbasic' 
+     CVSSourceCodeManager checkForExistingModule:'foo' package:'bar'   
+     CVSSourceCodeManager checkForExistingModule:'cg' package:'private'   
+    "
 
     "Created: 9.12.1995 / 19:13:37 / cg"
     "Modified: 19.12.1995 / 14:18:42 / stefan"
-    "Modified: 26.1.1996 / 16:10:22 / cg"
+    "Modified: 6.2.1996 / 17:39:51 / cg"
 !
 
 createContainerFor:aClass inModule:moduleDir package:packageDir container:fileName
+    "create a container - this does an initial checkin
+     (i.e. cvs add & cvs commit)"
+
     |fullName tempdir checkoutName cmdOut cmd tempFile idx aStream whatHappened l newRevision
      changeLog entry newString startIdx|
 
@@ -984,7 +1039,7 @@
 
     cmdOut := Filename newTemporary.
     cmdOut exists ifTrue:[
-	cmdOut remove.
+        cmdOut remove.
     ].
 
     fullName := moduleDir , '/' , packageDir , '/' , fileName.
@@ -997,16 +1052,16 @@
 
     cmd := 'cd ' , tempdir name , ';cvs checkout -l ' , checkoutName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
+        'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
 
-	cmdOut remove.
-	tempdir recursiveRemove.
-	('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
+        ^ false.
     ].
 
     "/
@@ -1015,22 +1070,22 @@
     tempFile := (tempdir name , '/' , checkoutName , '/' , fileName) asFilename.
     aStream := tempFile writeStream.
     aStream isNil ifTrue:[
-	('CVSMGR: temporary fileout failed -> ', tempFile name) errorPrintNL.
-	^ false
+        ('CVSMGR: temporary fileout failed -> ', tempFile name) errorPrintNL.
+        ^ false
     ].
 
     Class fileOutErrorSignal handle:[:ex |
-	'CVSMGR: fileout failed' errorPrintNL.
-	aStream close.
-	^ false
+        'CVSMGR: fileout failed' errorPrintNL.
+        aStream close.
+        ^ false
     ] do:[
-	aClass fileOutOn:aStream withTimeStamp:false.
+        aClass fileOutOn:aStream withTimeStamp:false.
     ].
     aStream close.
 
     tempFile exists ifFalse:[
-	'SOURCEMGR: temporary fileout failed' errorPrintNL.
-	^ false
+        'SOURCEMGR: temporary fileout failed' errorPrintNL.
+        ^ false
     ].
 
     "/
@@ -1038,16 +1093,16 @@
     "/
     cmd := 'cd ' , tempdir name , '/' , checkoutName , ';cvs add ' , fileName , ' > ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
 
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
+        'CVSMGR: failed to execute: ' errorPrint. cmd errorPrintNL.
 
-	cmdOut remove.
-	tempdir recursiveRemove.
-	('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ('CVSMGR: cannot checkout ' , checkoutName) errorPrintNL.
+        ^ false.
     ].
 
     cmdOut remove.
@@ -1057,23 +1112,27 @@
     "/
     cmd := 'cd ' , tempdir name , ';cvs commit -m "intitial checkin" 2> ' , cmdOut name.
     Verbose == true ifTrue:[
-	('CVSMGR: executing: ' , cmd) infoPrintNL.
+        ('CVSMGR: executing: ' , cmd) infoPrintNL.
     ].
     (OperatingSystem executeCommand:cmd) ifFalse:[
-	Verbose == true ifTrue:[
-	    'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
-	].
-	whatHappened := cmdOut contentsOfEntireFile asString.
-	self warn:'The following problem was reported by cvs:
+        Verbose == true ifTrue:[
+            'CVSMGR: failed to execute: ' infoPrint. cmd infoPrintNL.
+        ].
+        cmdOut fileSize > 0 ifTrue:[
+            whatHappened := cmdOut contentsOfEntireFile asString.
+        ] ifFalse:[
+            whatHappened := '<< no message >>'
+        ].
+        self warn:'The following problem was reported by cvs:
 
 ' , whatHappened , '
 
 The class has NOT been checked into the repository.'.
 
        'CVSMGR: cannot checkin modified class source' errorPrintNL.
-	cmdOut remove.
-	tempdir recursiveRemove.
-	^ false.
+        cmdOut remove.
+        tempdir recursiveRemove.
+        ^ false.
     ].
     whatHappened := cmdOut contentsOfEntireFile asString.
 
@@ -1086,25 +1145,25 @@
     "/ good - its in the CVS repository; now, we need the updated RCS header
     "/
     (whatHappened isNil or:[whatHappened isEmpty]) ifTrue:[
-	'CVSMGR: oops - unexpected empty commit command output' errorPrintNL.
+        'CVSMGR: oops - unexpected empty commit command output' errorPrintNL.
     ] ifFalse:[
-	whatHappened := whatHappened asCollectionOfLines asStringCollection.
-	idx := whatHappened indexOfLineStartingWith:'initial revision:'.
-	idx ~~ 0 ifTrue:[
-	    startIdx := 18
-	] ifFalse:[
-	    idx := whatHappened indexOfLineStartingWith:'new revision:'.
-	    idx ~~ 0 ifTrue:[
-		'CVSMGR: oops - container existed' errorPrintNL.
-		startIdx := 14.
-	    ] ifFalse:[
-		'CVSMGR: oops - unexpected commit command output (no new-revision info)' errorPrintNL.
-	    ]
-	].
-	idx ~~ 0 ifTrue:[
-	    l := whatHappened at:idx.
-	    newRevision := (l copyFrom:startIdx to:(l indexOf:$; startingAt:startIdx)-1) withoutSpaces.
-	]
+        whatHappened := whatHappened asCollectionOfLines asStringCollection.
+        idx := whatHappened indexOfLineStartingWith:'initial revision:'.
+        idx ~~ 0 ifTrue:[
+            startIdx := 18
+        ] ifFalse:[
+            idx := whatHappened indexOfLineStartingWith:'new revision:'.
+            idx ~~ 0 ifTrue:[
+                'CVSMGR: oops - container existed' errorPrintNL.
+                startIdx := 14.
+            ] ifFalse:[
+                'CVSMGR: oops - unexpected commit command output (no new-revision info)' errorPrintNL.
+            ]
+        ].
+        idx ~~ 0 ifTrue:[
+            l := whatHappened at:idx.
+            newRevision := (l copyFrom:startIdx to:(l indexOf:$; startingAt:startIdx)-1) withoutSpaces.
+        ]
     ].
 
     "/
@@ -1116,29 +1175,29 @@
     "/
 
     newRevision notNil ifTrue:[
-	changeLog := self 
-			revisionLogOf:aClass 
-			fromRevision:newRevision 
-			toRevision:newRevision
-			fileName:fileName
-			directory:packageDir
-			module:moduleDir.
+        changeLog := self 
+                        revisionLogOf:aClass 
+                        fromRevision:newRevision 
+                        toRevision:newRevision
+                        fileName:fileName
+                        directory:packageDir
+                        module:moduleDir.
 
-	(changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
-	    'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
-	] ifFalse:[
-	    entry := (changeLog at:#revisions) first.
-	    newString := self revisionStringFromLog:changeLog entry:entry.
-	    aClass updateVersionMethodFor:newString.
-	    ('CVSMGR: updated revisionString to:',newString) errorPrintNL
-	]
+        (changeLog isNil or:[(changeLog at:#revisions) size ~~ 1]) ifTrue:[
+            'CVSMGR: oops - failed to update revisionString (no log)' errorPrintNL
+        ] ifFalse:[
+            entry := (changeLog at:#revisions) first.
+            newString := self revisionStringFromLog:changeLog entry:entry.
+            aClass updateVersionMethodFor:newString.
+            ('CVSMGR: updated revisionString to:',newString) errorPrintNL
+        ]
     ].
 
     tempdir recursiveRemove.
     ^ true
 
     "Created: 9.12.1995 / 19:13:37 / cg"
-    "Modified: 17.12.1995 / 16:02:06 / cg"
+    "Modified: 6.2.1996 / 17:55:33 / cg"
 !
 
 createModule:moduleName
@@ -1277,169 +1336,174 @@
 
      The returned information is a structure (IdentityDictionary)
      filled with:
-	    #container          -> the RCS container file name 
-	    #filename           -> the actual source file name
-	    #newestRevision     -> the revisionString of the newest revision
-	    #numberOfRevisions  -> the number of revisions in the container
-	    #revisions          -> collection of per-revision info (see below)
+            #container          -> the RCS container file name 
+            #filename           -> the actual source file name
+            #newestRevision     -> the revisionString of the newest revision
+            #numberOfRevisions  -> the number of revisions in the container
+            #revisions          -> collection of per-revision info (see below)
 
-	    rev1 / rev2 specify from which revisions a logEntry is wanted:
-	     -If rev1 is nil, the first revision is the initial revision
-	      otherwise, the log starts with that revision.
-	     -If rev2 is nil, the last revision is the newest revision
-	      otherwise, the log ends with that revision.
+            rev1 / rev2 specify from which revisions a logEntry is wanted:
+             -If rev1 is nil, the first revision is the initial revision
+              otherwise, the log starts with that revision.
+             -If rev2 is nil, the last revision is the newest revision
+              otherwise, the log ends with that revision.
 
-	     -If both are nil, all logEntries are extracted.
-	     -If both are 0 (not nil), no logEntries are extracted (i.e. only the header).
+             -If both are nil, all logEntries are extracted.
+             -If both are 0 (not nil), no logEntries are extracted (i.e. only the header).
 
-	    per revision info consists of one record per revision:
+            per revision info consists of one record per revision:
 
-	      #revision              -> the revision string
-	      #author                -> who checked that revision into the repository
-	      #date                  -> when was it checked in
-	      #state                 -> the RCS state
-	      #numberOfChangedLines  -> the number of changed line w.r.t the previous
+              #revision              -> the revision string
+              #author                -> who checked that revision into the repository
+              #date                  -> when was it checked in
+              #state                 -> the RCS state
+              #numberOfChangedLines  -> the number of changed line w.r.t the previous
 
-	    revisions are ordered newest first 
-	    (i.e. the last entry is for the initial revision; the first for the most recent one)
-	"
+            revisions are ordered newest first 
+            (i.e. the last entry is for the initial revision; the first for the most recent one)
+        "
 
     |tempDir cmd fullName modulePath inStream inHeaderInfo atEnd line revArg revLine1 revLine2 idx
      info record revisionRecords s headerOnly|
 
     CVSRoot isNil ifTrue:[
-	'CVSMGR: CVSROOT not set' infoPrintNL.
-	^ nil
+        'CVSMGR: CVSROOT not set' infoPrintNL.
+        ^ nil
     ].
 
     modulePath :=  moduleDir , '/' , packageDir. 
     fullName :=  modulePath , '/' , classFileName.
     tempDir := self createTempDirectory:nil forModule:nil.
     [
-	self createEntryFor:fullName 
-	     in:(tempDir construct:modulePath) 
-	     revision:'1.1' 
-	     date:'dummy' 
-	     special:''
-	     overwrite:false.
+        self createEntryFor:fullName 
+             in:(tempDir construct:modulePath) 
+             revision:'1.1' 
+             date:'dummy' 
+             special:''
+             overwrite:false.
 
-	revArg := ''.
-	headerOnly := false.
-	(rev1 notNil or:[rev2 notNil]) ifTrue:[
-	    (rev1 == 0 and:[rev2 == 0]) ifTrue:[
-		revArg := '-h'.
-		headerOnly := true.
-	    ] ifFalse:[
-		revArg := '-r'.
-		rev1 notNil ifTrue:[
-		    revArg := revArg , rev1
-		].
-		revArg := revArg , ':'.
-		rev2 notNil ifTrue:[
-		    revArg := revArg , rev2
-		].
-	    ]
-	].
+        revArg := ''.
+        headerOnly := false.
+        (rev1 notNil or:[rev2 notNil]) ifTrue:[
+            (rev1 == 0 and:[rev2 == 0]) ifTrue:[
+                revArg := '-h'.
+                headerOnly := true.
+            ] ifFalse:[
+                revArg := '-r'.
+                rev1 notNil ifTrue:[
+                    revArg := revArg , rev1
+                ].
+                revArg := revArg , ':'.
+                rev2 notNil ifTrue:[
+                    revArg := revArg , rev2
+                ].
+            ]
+        ].
 
-	self activityNotification:'reading log'.
-	cmd := 'cd ', tempDir name, '; cvs -d ', CVSRoot, ' log ' , revArg , ' ' , fullName.
+        self activityNotification:'reading log'.
+        cmd := 'cd ', tempDir name, '; cvs -d ', CVSRoot, ' log ' , revArg , ' ' , fullName.
     "/ cmd printNL.
-	inStream := PipeStream readingFrom:cmd.
-	inStream isNil ifTrue:[
-	    ('CVSMGR: cannot open pipe to cvs log ', fullName) infoPrintNL.
-	    ^ nil
-	].
+        inStream := PipeStream readingFrom:cmd.
+        inStream isNil ifTrue:[
+            ('CVSMGR: cannot open pipe to cvs log ', fullName) infoPrintNL.
+            ^ nil
+        ].
 
-	"/
-	"/ read the commands pipe output and extract the container info
-	"/
-	info := IdentityDictionary new.
-	inHeaderInfo := true.
-	[inHeaderInfo and:[inStream atEnd not]] whileTrue:[
-	    line:= inStream nextLine.
-	    line notNil ifTrue:[
-		|gotIt|
+        "/
+        "/ read the commands pipe output and extract the container info
+        "/
+        info := IdentityDictionary new.
+        inHeaderInfo := true.
+        [inHeaderInfo and:[inStream atEnd not]] whileTrue:[
+            line:= inStream nextLine.
+            line notNil ifTrue:[
+                |gotIt|
 
-		gotIt := false.
-		#('RCS file:' #container
-		  'Working file:' #filename
-		  'head:' #newestRevision
-		  'total revisions:' #numberOfRevisions
-		 ) pairWiseDo:[:word :key |
-		    gotIt ifFalse:[
-			s := line restAfter:word withoutSeparators:true.
-			s notNil ifTrue:[info at:key put:s. gotIt := true].                        
-		    ]
-		].
-		gotIt ifFalse:[
-		    (line startsWith:'description:') ifTrue:[inHeaderInfo := false].
-		]
-	    ]
-	].
-	inStream nextLine. "/ skip separating line after description.
+                gotIt := false.
+                #('RCS file:' #container
+                  'Working file:' #filename
+                  'head:' #newestRevision
+                  'total revisions:' #numberOfRevisions
+                 ) pairWiseDo:[:word :key |
+                    gotIt ifFalse:[
+                        s := line restAfter:word withoutSeparators:true.
+                        s notNil ifTrue:[info at:key put:s. gotIt := true].                        
+                    ]
+                ].
+                gotIt ifFalse:[
+                    (line startsWith:'description:') ifTrue:[inHeaderInfo := false].
+                ]
+            ]
+        ].
+        inStream nextLine. "/ skip separating line after description.
 
-	"/ strip selected revisions from the total-revisions entry
-	s := info at:#numberOfRevisions.
-	(idx := s indexOf:$;) ~~ 0 ifTrue:[
-	    info at:#numberOfRevisions put:(Integer readFrom:(s copyTo:idx - 1))
-	].
+        info isEmpty ifTrue:[
+            ('CVSMGR: no log for ', fullName) infoPrintNL.
+            ^ nil
+        ].
 
-	headerOnly ifFalse:[
-	    "/
-	    "/ continue to read the commands pipe output 
-	    "/ and extract revision info records
-	    "/
-	    revisionRecords := OrderedCollection new:(info at:#numberOfRevisions).
-	    info at:#revisions put:revisionRecords.
+        "/ strip selected revisions from the total-revisions entry
+        s := info at:#numberOfRevisions.
+        (idx := s indexOf:$;) ~~ 0 ifTrue:[
+            info at:#numberOfRevisions put:(Integer readFrom:(s copyTo:idx - 1))
+        ].
+
+        headerOnly ifFalse:[
+            "/
+            "/ continue to read the commands pipe output 
+            "/ and extract revision info records
+            "/
+            revisionRecords := OrderedCollection new:(info at:#numberOfRevisions).
+            info at:#revisions put:revisionRecords.
 
-	    atEnd := false.
-	    [atEnd or:[inStream atEnd]] whileFalse:[
-		revLine1 := inStream nextLine.
-		[revLine1 notNil and:[(revLine1 startsWith:'revision ') not]]
-		    whileTrue:[revLine1 := inStream nextLine.].
-		revLine2 := inStream nextLine.
-		(revLine1 notNil and:[revLine2 notNil]) ifTrue:[
-		    record := IdentityDictionary new.
-		    record at:#revision put:(revLine1 asCollectionOfWords at:2).
-		    "/ decompose date/author/state etc.
-		    (revLine2 asCollectionOfSubstringsSeparatedBy:$;) do:[:info |
-			|subEntry|
-			subEntry := info withoutSeparators.
-			#('date:' #date
-			  'author:' #author 
-			  'state:' #state 
-			  'lines:' #numberOfChangedLines
-			 ) pairWiseDo:[:word :key |
-			    s := subEntry restAfter:word withoutSeparators:true.
-			    s notNil ifTrue:[record at:key put:s.].                        
-			].
-		    ].
+            atEnd := false.
+            [atEnd or:[inStream atEnd]] whileFalse:[
+                revLine1 := inStream nextLine.
+                [revLine1 notNil and:[(revLine1 startsWith:'revision ') not]]
+                    whileTrue:[revLine1 := inStream nextLine.].
+                revLine2 := inStream nextLine.
+                (revLine1 notNil and:[revLine2 notNil]) ifTrue:[
+                    record := IdentityDictionary new.
+                    record at:#revision put:(revLine1 asCollectionOfWords at:2).
+                    "/ decompose date/author/state etc.
+                    (revLine2 asCollectionOfSubstringsSeparatedBy:$;) do:[:info |
+                        |subEntry|
+                        subEntry := info withoutSeparators.
+                        #('date:' #date
+                          'author:' #author 
+                          'state:' #state 
+                          'lines:' #numberOfChangedLines
+                         ) pairWiseDo:[:word :key |
+                            s := subEntry restAfter:word withoutSeparators:true.
+                            s notNil ifTrue:[record at:key put:s.].                        
+                        ].
+                    ].
 
-		    s := nil.
-		    line := inStream nextLine.
-		    [atEnd or:[line isNil or:[line startsWith:'--------']]] whileFalse:[
-			(line startsWith:'==========') ifTrue:[
-			    atEnd := true.
-			] ifFalse:[
-			    (line withoutSpaces = '.') ifTrue:[
-				line := '*** empty log message ***'
-			    ].
-			    s isNil ifTrue:[
-				s := line
-			    ] ifFalse:[
-				s := s , Character cr asString , line.
-			    ].
-			    line := inStream nextLine.
-			]
-		    ].
-		    record at:#logMessage put:s.
-		    revisionRecords add:record.
-		]
-	    ].
-	].
-	inStream close.
+                    s := nil.
+                    line := inStream nextLine.
+                    [atEnd or:[line isNil or:[line startsWith:'--------']]] whileFalse:[
+                        (line startsWith:'==========') ifTrue:[
+                            atEnd := true.
+                        ] ifFalse:[
+                            (line withoutSpaces = '.') ifTrue:[
+                                line := '*** empty log message ***'
+                            ].
+                            s isNil ifTrue:[
+                                s := line
+                            ] ifFalse:[
+                                s := s , Character cr asString , line.
+                            ].
+                            line := inStream nextLine.
+                        ]
+                    ].
+                    record at:#logMessage put:s.
+                    revisionRecords add:record.
+                ]
+            ].
+        ].
+        inStream close.
     ] valueNowOrOnUnwindDo:[
-	tempDir recursiveRemove
+        tempDir recursiveRemove
     ].
     ^ info
 
@@ -1453,8 +1517,8 @@
     "
 
     "Created: 16.11.1995 / 13:25:30 / cg"
-    "Modified: 16.12.1995 / 18:53:02 / cg"
     "Modified: 20.12.1995 / 11:06:11 / stefan"
+    "Modified: 6.2.1996 / 16:22:43 / cg"
 !
 
 writeHistoryLogSince:timeGoal filterSTSources:filter filterUser:userFilter to:aStream
@@ -1537,6 +1601,6 @@
 !CVSSourceCodeManager class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic3/CVSSourceCodeManager.st,v 1.77 1996-01-26 15:12:01 ah Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic3/CVSSourceCodeManager.st,v 1.78 1996-02-06 20:28:12 cg Exp $'
 ! !
 CVSSourceCodeManager initialize!