/[meta-cvs]/meta-cvs/F-9A67B1893CE1CF23455CD1EF0F486B65
ViewVC logotype

Diff of /meta-cvs/F-9A67B1893CE1CF23455CD1EF0F486B65

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.7 by kaz, Sun Oct 6 05:25:31 2002 UTC revision 1.7.2.7 by kaz, Sat Jan 31 23:07:09 2004 UTC
# Line 11  Line 11 
11  (provide "convert")  (provide "convert")
12    
13  (defun remove-attic-component (path)  (defun remove-attic-component (path)
14    (let* ((split-path (split-fields path "/"))    (let ((split-path (nreverse (split-fields path "/")))
15           (len (length split-path)))          (attic-p nil))
16      (when (and (>= len 2) (string= (nth (- len 2) split-path) "Attic"))      (when (string= (first split-path) "Attic")
17        (setf split-path (append (butlast (butlast split-path))        (pop split-path)
18                                 (last split-path))))        (setf attic-p t))
19      (reduce #'(lambda (x y) (format nil "~a/~a" x y)) split-path)))      (values (reduce #'(lambda (x y) (format nil "~a/~a" x y))
20                        (nreverse split-path)
21                        :initial-value ".")
22                attic-p)))
23    
24  (defun classify-tags (tags)  (defun classify-tags (tags)
25    (let (version-tags branch-tags)    (let (version-tags branch-tags)
# Line 38  Line 41 
41      (if (not created)      (if (not created)
42        (error "unable to create directory ~a." target-dir)))        (error "unable to create directory ~a." target-dir)))
43    
44    (let (filemap all-version-tags all-branch-tags)    (let (filemap all-version-tags all-branch-tags attic-made)
45      (current-dir-restore      (current-dir-restore
46          (chatter-info "descending into ~a~%" source-dir)
47        (chdir source-dir)        (chdir source-dir)
48        (for-each-file-info (fi ".")        (for-each-file-info (fi ".")
49            (when (and (directory-p fi)
50                       (path-equal (basename (file-name fi)) "CVS"))
51              (skip))
52          (when (regular-p fi)          (when (regular-p fi)
53            (let ((canon-name (canonicalize-path (file-name fi))))            (let ((canon-name (canonicalize-path (file-name fi))))
54              (multiple-value-bind (suffix v-suffix-free-name)              (multiple-value-bind (suffix basename dir)
55                                   (suffix canon-name #\,)                                   (suffix canon-name #\,)
56                (when (and suffix (string= suffix "v"))                (multiple-value-bind (no-attic-dir attic-p)
57                  (let ((attic-free-name                                     (remove-attic-component (or dir "."))
58                          (remove-attic-component v-suffix-free-name))                  (when (and suffix (string= suffix "v"))
59                        (f-name (mapping-generate-id :suffix (suffix v-suffix-free-name)                    (let* ((no-attic-suffix-name
60                                                     :no-dir t)))                             (canonicalize-path (path-cat no-attic-dir basename)))
61                    (link canon-name (path-cat *up-dir*                           (f-name (mapping-generate-id :suffix (suffix basename)
62                                               target-dir                                                        :no-dir t))
63                                               (format nil "~A,v" f-name)))                           (rcs-name (apply #'path-cat `(,*up-dir* ,target-dir
64                    (push (make-mapping-entry :kind :file                                                         ,@(if attic-p '("Attic"))
65                                              :id (path-cat *mcvs-dir* f-name)                                                         ,(format nil "~A,v"
66                                              :path attic-free-name                                                                  f-name)))))
67                                              :executable (executable-p fi))                      (when attic-p
68                          filemap)                        (unless attic-made
69                    (with-open-file (f (parse-posix-namestring canon-name)                          (ensure-directories-exist rcs-name)
70                                       :direction :input)                          (setf attic-made t)))
71                      (chatter-info "scanning ~a.~%" canon-name)                      (chatter-info "hard linking ~a -> ~a~%"
72                      (let ((rcs-file (rcs-parse f)))                                    canon-name
73                        (multiple-value-bind (version-tags branch-tags)                                    rcs-name)
74                                             (classify-tags (rcs-admin-symbols (rcs-file-admin rcs-file)))                      (link canon-name rcs-name)
75                          (setf all-version-tags (nunion all-version-tags                      (push (make-mapping-entry :kind :file
76                                                         version-tags                                                :id (path-cat *mcvs-dir* f-name)
77                                                         :test #'string=))                                                :path no-attic-suffix-name
78                          (setf all-branch-tags (nunion all-branch-tags branch-tags                                                :executable (executable-p fi))
79                                                        :test #'string=))))))))))))                            filemap)
80                        (with-open-file (f (parse-posix-namestring canon-name)
81                                           :direction :input)
82                          (chatter-info "scanning ~a~%" canon-name)
83                          (let ((rcs-file (rcs-parse f)))
84                            (multiple-value-bind (version-tags branch-tags)
85                                                 (classify-tags (rcs-admin-symbols (rcs-file-admin rcs-file)))
86                              (setf all-version-tags (nunion all-version-tags
87                                                             version-tags
88                                                             :test #'string=))
89                              (setf all-branch-tags (nunion all-branch-tags branch-tags
90                                                            :test #'string=)))))))))))))
91    
92      (current-dir-restore      (current-dir-restore
93        (chdir target-dir)        (chdir target-dir)
94        (chatter-info "Writing map.")        (chatter-info "writing ~a~%" *mcvs-map-name*)
95        (mapping-write filemap *mcvs-map-name*)        (mapping-write filemap *mcvs-map-name* :sort-map t)
96    
97        (execute-program `("ci" "-mMeta-CVS MAP file created by mcvs convert."        (execute-program `("ci" "-mMeta-CVS MAP file created by mcvs convert."
98                           "-t/dev/null" ,*mcvs-map-name*))                           "-t/dev/null" ,*mcvs-map-name*))
99        (execute-program `("chmod" "ug+rw" ,(format nil "~A,v" *mcvs-map-name*)))        (execute-program `("chmod" "ug+rw" ,(format nil "~A,v" *mcvs-map-name*)))
100    
101        (execute-program-xargs '("rcs")        (chatter-info "setting up version and branch tags in ~a~%" *mcvs-map-name*)
102                               (mapcar #'(lambda (tag)        (unless (null all-version-tags)
103                                           (format nil "-n~A:1.1" tag))          (execute-program-xargs '("rcs")
104                                       all-version-tags)                                 (mapcar #'(lambda (tag)
105                               (list *mcvs-map-name*))                                             (format nil "-n~A:1.1" tag))
106                                           all-version-tags)
107                                   (list *mcvs-map-name*)))
108    
109        (let ((branch-counter 0))        (let ((branch-counter 0))
110          (execute-program-xargs '("rcs")          (unless (null all-branch-tags)
111                                 (mapcar #'(lambda (tag)            (execute-program-xargs '("rcs")
112                                             (format nil                                   (mapcar #'(lambda (tag)
113                                                     "-n~A:1.1.0.~A"                                               (format nil
114                                                     tag (+ 2 branch-counter)))                                                       "-n~A:1.1.0.~A"
115                                         all-branch-tags)                                                       tag (incf branch-counter
116                                 (list *mcvs-map-name*))))))                                                                 2)))
117                                             all-branch-tags)
118                                     (list *mcvs-map-name*)))))))
119    
120  (defun mcvs-convert-wrapper (cvs-options cvs-command-options mcvs-args)  (defun mcvs-convert-wrapper (cvs-options cvs-command-options mcvs-args)
121    (declare (ignore cvs-options cvs-command-options))    (declare (ignore cvs-options cvs-command-options))
122    (if (/= (length mcvs-args) 2)    (if (/= (length mcvs-args) 2)
123      (error "specify cvs source dir and new target dir."))      (error "specify cvs source dir and new target dir."))
124    (mcvs-convert (first mcvs-args) (second mcvs-args)))    (mcvs-convert (first mcvs-args) (second mcvs-args)))
125    
126    (defconstant *convert-help*
127    "Syntax:
128    
129      mcvs convert source-cvs-module target-mcvs-module
130    
131    Options:
132    
133      None.
134    
135    Semantics:
136    
137      The convert command builds a Meta-CVS module directly out of the RCS files of
138      a CVS module.  It must be run in the root directory of a CVS repository.
139      It requires the chmod and rcs command line tools.
140    
141      The algorithm is extremely naive. A list of the pathnames of the RCS files
142      is collected, as the basis for creating the MAP file. The Attic directory
143      components are removed from these paths, and the ,v suffixes are stripped.
144    
145      The execute property of files is lifted from the permission bits on
146      the RCS files.
147    
148      The MAP,v file is created using the ``rcs ci'' command.
149    
150      The F- files are generated as hard links to the RCS files, to save space
151      and avoid the overhead of copying.
152    
153      All of the RCS files are scanned to find version and branch tags.  Quite
154      naively, the version tags are installed in the MAP file, all pointing to
155      revision 1.1. The branch tags are installed in MAP, pointing to revisions
156      1.1.0.2, 1.1.0.4, ...  This is a lame attempt to make it possible to check
157      out past baselines. But note that the contents of MAP don't vary: only a
158      single version node is generated with a fixed set of files. It is not taken
159      into consideration that some of the CVS files may be deleted in the head
160      revision or some branches.  Therefore, when the resulting Meta-CVS project is
161      checked out, or when past versions are retrieved, there may be complaints
162      from Meta-CVS about nonexistent files.
163    
164      The complaints about nonexistent files may be fixed at the tips of the
165      main trunk or branches using the ``mcvs remap'' command which will purge
166      the working MAP of entries for F- files for which no working copy is found.
167      A commit will then commit the change so that subsequent work may continue
168      without any more complaints.
169    
170      The hard linking of the original RCS objects under F- names means that any
171      permission, ownership or time-stamp changes done in the CVS module will
172      affect the content of the Meta-CVS module and vice versa. Destructive
173      modifications to the file contents, ditto. Be careful!
174    
175      If the hard links make you nervous, do a deep copy of the module,
176      using ``cp -a source-dir target-dir''.
177    
178      Note that CVS does not destructively manipulate RCS files. A commit
179      or tagging operation creates a new RCS object which atomically replaces the
180      old hard link. This means that a commit to a file in the Meta-CVS module will
181      not affect the CVS module and vice versa.")

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.7.2.7

  ViewVC Help
Powered by ViewVC 1.1.5