Eskil

Diff
Login

Differences From Artifact [db43cf957f]:

To Artifact [299b30ea0a]:


11
12
13
14
15
16
17

18
19
20
21
22
23
24
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25







+








namespace eval vcsvfs {
    variable DataRefChan
    variable mpoints {}
    namespace eval fossil {}
    namespace eval svn {}
    namespace eval git {}
    namespace eval hg {}
}

# Create a Virtual File System showing a revision of a fossil checkout
#
# dir: Directory in a fossil checkout
# rev: Revision to mount
#
338
339
340
341
342
343
344









































































345
346
347
348
349
350
351
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








proc vcsvfs::svn::unmount {dir} {
    variable ::vcsvfs::mpoints
    # TBD: Find the mountpoint
    #dict unset mpoints $mountpoint
    #vfs::filesystem unmount $mountpoint
}

# Create a Virtual File System showing a revision of a HG checkout
#
# dir: Directory in an HG checkout
# rev: Revision to mount
#
# Returns: path to the generated VFS
proc vcsvfs::hg::mount {dir rev} {
    variable ::vcsvfs::mpoints
    set dir [file normalize $dir]

    # Command must be run within the dir, so temporarily change pwd
    set oldpwd [pwd]
    cd $dir

    # The mount point will normally be at the wc root, even if
    # a sub directory was given.
    # Locate root for the given directory.
    set root [exec hg root]
    # TBD: Always root at given dir, for speed
    #set root .
    #set root [file normalize $root]
    #cd $root

    # Getting files via manifest
    set allfiles [exec hg manifest --debug -r $rev]
    # Expected line format:
    # sha1sum perms *? name
    foreach line [split $allfiles \n] {
        # Each line is one file name
        regexp {^(\S+)\s+\S+\s+\*?\s*(\S.*)$} $line -> sha fName
        dict set finfo $fName isfile 1
        dict set finfo $fName isdir 0
        dict set finfo $fName "sha" $sha
        dict set finfo $fName type file
        # Fake mtime and size from sha, to make same look same
        dict set finfo $fName mtime [scan [string range $sha 0 6] %x]
        dict set finfo $fName size  [scan [string range $sha 7 9] %x]
        # Mark all known directory paths and build up file tree info
        set parentStr ""
        foreach dirPath [file split $fName] {
            dict set finfo $parentStr child $dirPath 1
            dict set finfo $parentStr isfile 0
            dict set finfo $parentStr isdir 1
            dict set finfo $parentStr type directory
            set parentStr [file join $parentStr $dirPath]
        }
    }

    # TBD: Any way to get file sizes and mtimes from HG?

    cd $oldpwd

    # Generate a mount point.
    set tail [string range $dir [string length $root] end]
    set mountpoint "${root} ($rev)"

    dict set mpoints $mountpoint "finfo" $finfo
    dict set mpoints $mountpoint "origroot" $root
    dict set mpoints $mountpoint "rev" $rev
    dict set mpoints $mountpoint "vcstype" hg
    vfs::filesystem mount $mountpoint [list vcsvfs::Vfs]

    set result $mountpoint$tail
    return $result
}

proc vcsvfs::hg::unmount {dir} {
    variable ::vcsvfs::mpoints
    # TBD: Find the mountpoint
    #dict unset mpoints $mountpoint
    #vfs::filesystem unmount $mountpoint
}

# Create a Virtual File System showing a revision of a GIT checkout
#
# dir: Directory in an GIT checkout
# rev: Revision to mount
#
# Returns: path to the generated VFS
514
515
516
517
518
519
520












521
522
523
524
525
526
527
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613







+
+
+
+
+
+
+
+
+
+
+
+







proc vcsvfs::svn::openFile {rootD relative mode} {
    set oldpwd [pwd]
    cd [dict get $rootD "origroot"]
    set rev [dict get $rootD rev]
    # Read through a pipe to get requested mode
    set chId [open [list |svn cat -r $rev $relative] $mode]
    cd $oldpwd

    return [list $chId [list vcsvfs::ReadAllBeforeClose $chId]]
}

# Extract file data from HG revision
proc vcsvfs::hg::openFile {rootD relative mode} {
    set oldpwd [pwd]
    cd [dict get $rootD "origroot"]
    set rev [dict get $rootD rev]
    # Read through a pipe to get requested mode
    set chId [open [list |hg cat -r $rev $relative] $mode]
    cd $oldpwd

    return [list $chId [list vcsvfs::ReadAllBeforeClose $chId]]
}

# Some notes about git commands that can be good to have
proc vcsvfs::git::openFile {rootD relative mode} {
    set oldpwd [pwd]