| | @@ -111,23 +111,13 @@ |
| 111 | 111 | set rcs [fileutil::stripPath $base $path] |
| 112 | 112 | if {[IsCVSAdmin $rcs]} continue |
| 113 | 113 | if {![IsRCSArchive $path]} continue |
| 114 | 114 | |
| 115 | 115 | set usr [UserPath $rcs isattic] |
| 116 | | - if {[IsSuperceded $base $rcs $usr $isattic]} continue |
| 117 | | - |
| 118 | | - # XXX Checkme: not sure if this will still fail in the case where a directory does conflict with a file XXX |
| 119 | | - if { |
| 120 | | - [fileexists_cs $base/$usr] && |
| 121 | | - [fileisdir_cs $base/$usr] |
| 122 | | - } { |
| 123 | | - trouble fatal "Directory name conflicts with filename." |
| 124 | | - trouble fatal "Please remove or rename one of the following:" |
| 125 | | - trouble fatal " $base/$usr" |
| 126 | | - trouble fatal " $base/$rcs" |
| 127 | | - continue |
| 128 | | - } |
| 116 | + |
| 117 | + if {[CheckForAndReportPathConflicts $base $rcs $usr $isattic]} continue |
| 118 | + if {[HandleDotFile $base $rcs usr $isattic]} continue |
| 129 | 119 | |
| 130 | 120 | log write 4 collar "Found $rcs" |
| 131 | 121 | $project addfile $rcs $usr [file executable $rcs] |
| 132 | 122 | |
| 133 | 123 | incr n |
| | @@ -158,15 +148,26 @@ |
| 158 | 148 | |
| 159 | 149 | typemethod ignore_conflicting_attics {} { |
| 160 | 150 | set myignore 1 |
| 161 | 151 | return |
| 162 | 152 | } |
| 153 | + |
| 154 | + typemethod accept_and_convert_dotfiles {} { |
| 155 | + set myconvertdot 1 |
| 156 | + return |
| 157 | + } |
| 163 | 158 | |
| 164 | 159 | # # ## ### ##### ######## ############# |
| 165 | 160 | ## Internal methods |
| 166 | 161 | |
| 167 | | - typevariable myignore 0 |
| 162 | + typevariable myignore 0 ; # Flag. When set Attic files |
| 163 | + # superceded by regular files |
| 164 | + # ignored. |
| 165 | + typevariable myconvertdot 0 ; # Flag. When set dotfiles do not |
| 166 | + # cause rejection, but their names |
| 167 | + # are converted to a dotless form |
| 168 | + # ('dot-' prefix instead of '.'). |
| 168 | 169 | |
| 169 | 170 | proc FilterAtticSubdir {base path} { |
| 170 | 171 | # This command is used by the traverser to prevent it from |
| 171 | 172 | # scanning into subdirectories of an Attic. We get away with |
| 172 | 173 | # checking the immediate parent directory of the current path |
| | @@ -186,13 +187,18 @@ |
| 186 | 187 | trouble warn $msg |
| 187 | 188 | return 0 |
| 188 | 189 | } |
| 189 | 190 | |
| 190 | 191 | proc IsCVSAdmin {rcs} { |
| 191 | | - if {![string match CVSROOT/* $rcs]} {return 0} |
| 192 | | - log write 4 collar "Ignored $rcs, administrative archive" |
| 193 | | - return 1 |
| 192 | + if { |
| 193 | + [string match {CVSROOT/*} $rcs] || |
| 194 | + [string match {.cvsignore*} [file tail $rcs]] |
| 195 | + } { |
| 196 | + log write 4 collar "Ignored $rcs, administrative archive" |
| 197 | + return 1 |
| 198 | + } |
| 199 | + return 0 |
| 194 | 200 | } |
| 195 | 201 | |
| 196 | 202 | proc UserPath {rcs iav} { |
| 197 | 203 | upvar 1 $iav isattic |
| 198 | 204 | |
| | @@ -237,10 +243,72 @@ |
| 237 | 243 | } else { |
| 238 | 244 | trouble warn "Ignored $rcs, superceded archive" |
| 239 | 245 | } |
| 240 | 246 | return 1 |
| 241 | 247 | } |
| 248 | + |
| 249 | + # In the future we should move the activity below into the fossil |
| 250 | + # backend, as the exact set of paths requiring translation, and |
| 251 | + # how to translate them, depends entirely on the limitations |
| 252 | + # imposed by the destination repository. |
| 253 | + |
| 254 | + proc HandleDotFile {base rcs usrvar isattic} { |
| 255 | + ::variable myconvertdot |
| 256 | + upvar 1 $usrvar usr |
| 257 | + |
| 258 | + set dedot [DeDot $usr] |
| 259 | + if {$dedot eq $usr} { return 0 } |
| 260 | + |
| 261 | + # Ok, we now have established that the path has to be |
| 262 | + # translated. Which as already happened as part of the check |
| 263 | + # above. Left is to report the action, and to check if the new |
| 264 | + # path collides with existing files and directories. |
| 265 | + |
| 266 | + if {!$myconvertdot} { |
| 267 | + trouble warn "Ignored $rcs, is a dot-file" |
| 268 | + return 1 |
| 269 | + } |
| 270 | + |
| 271 | + log write 2 collar "Convert $rcs, is a dot-file" |
| 272 | + set usr $dedot |
| 273 | + |
| 274 | + return [CheckForAndReportPathConflicts $base $rcs $usr $isattic] |
| 275 | + } |
| 276 | + |
| 277 | + proc DeDot {path} { |
| 278 | + set res {} |
| 279 | + foreach segment [file split $path] { |
| 280 | + lappend res [expr { |
| 281 | + [string match {.*} $segment] |
| 282 | + ? "dot-[string range $segment 1 end]" |
| 283 | + : $segment |
| 284 | + }] |
| 285 | + } |
| 286 | + return [eval [linsert $res 0 file join]] |
| 287 | + #8.5: return [file join {*}$res] |
| 288 | + } |
| 289 | + |
| 290 | + proc CheckForAndReportPathConflicts {base rcs usr isattic {intro {}}} { |
| 291 | + if {[IsSuperceded $base $rcs $usr $isattic]} { return 1 } |
| 292 | + |
| 293 | + # XXX Checkme: not sure if this will still fail in the case |
| 294 | + # where a directory does conflict with a file XXX |
| 295 | + if { |
| 296 | + [fileexists_cs $base/$usr] && |
| 297 | + [fileisdir_cs $base/$usr] |
| 298 | + } { |
| 299 | + if {$intro ne {}} { |
| 300 | + trouble fatal $intro |
| 301 | + } |
| 302 | + trouble fatal "Directory name conflicts with filename." |
| 303 | + trouble fatal "Please remove or rename one of the following:" |
| 304 | + trouble fatal " $base/$usr" |
| 305 | + trouble fatal " $base/$rcs" |
| 306 | + return 1 |
| 307 | + } |
| 308 | + return 0 |
| 309 | + } |
| 242 | 310 | |
| 243 | 311 | # # ## ### ##### ######## ############# |
| 244 | 312 | ## Configuration |
| 245 | 313 | |
| 246 | 314 | pragma -hasinstances no ; # singleton |
| 247 | 315 | |