Eskil

Diff
Login

Differences From Artifact [c0cc94a426]:

To Artifact [3ea274676f]:


43
44
45
46
47
48
49
50

51
52
53
54
55
56





57
58
59
60
61
62
63
43
44
45
46
47
48
49

50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65
66







-
+




-
-
+
+
+
+
+








# eskil::rev::XXX::get {filename outfile rev}
#
# Get a revision of a file and place it in outfile.
# rev is in any format understood by this system, and
# should be retrieved from ParseRevs

# eskil::rev::XXX::getPatch {revs {files {}}}
# eskil::rev::XXX::getPatch {revs files {fileListName {}}}
#
# Get a patch of the file tree, between the revisions given.
# revs is in any format understood by this system, and
# should be retrieved from ParseRevs
# An optional list of files that should be included can be given.
# Note that current directory must be correct before calling.
# If files is non-empty it is a list of files that should be included.
# If fileListName is given, it is a variable name where to place the
# list of files affected by the patch. The list should be cleaned
# through lsort -dictionary -unique.
# NOTE that current directory must be correct before calling.

# eskil::rev::XXX::getChangedFiles {dir revs}
#
# Get a list of files changed between the revisions given.
# revs is in any format understood by this system, and
# should be retrieved from ParseRevs

274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291







-
+








    if {$old != ""} {
        cd $old
    }
}

# Get a CVS patch
proc eskil::rev::CVS::getPatch {revs {files {}}} {
proc eskil::rev::CVS::getPatch {revs files {fileListName {}}} {
    if {$::Pref(context) > 0} {
        set context $::Pref(context)
    } else {
        set context 5
    }
    # TODO: support files
    set cmd [list exec cvs diff -U $context]
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
426
427
428
429
430
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
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445







-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-













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







        if {[regexp {^(\S+)\s+(\S+)$} $line -> pre file]} {
            lappend changes [file join $dir $file]
        }
    }
    return $changes
}

# Get a SVN patch
proc eskil::rev::SVN::getPatch {revs {files {}}} {
    set cmd [list exec svn diff]
# Common helper for SVN revisions
proc eskil::rev::SVN::RevsToCmd {revs} {
    set cmd {}
    foreach rev $revs {
        # TODO: What happens in strange combinations ?
        if {[string match "*://*" $rev]} {
            # Full URL
            lappend cmd $rev
        } else {
            lappend cmd -r $rev
        }
    }
    lappend cmd {*}$files

    if {[catch {eval $cmd} res]} {
        tk_messageBox -icon error -title "SVN error" -message $res
        return ""
    }
    return $res
}

proc eskil::rev::SVN::getChangedFiles {dir revs} {
    # Must call SVN in top dir to get full changeset
    GetTopDir $dir top tail
    set cmd [list execDir $top svn diff --summarize]
    set revs2 {}
    foreach rev $revs {
        # TODO: What happens in strange combinations ?
        if {[string match "*://*" $rev]} {
            # Full URL
            lappend cmd $rev
        } else {
            lappend revs2 $rev
        }
    }
    if {[llength $revs2] > 0} {
        lappend cmd -r [join $revs2 :]
    }
    return $cmd
}

# Get a SVN patch
proc eskil::rev::SVN::getPatch {revs files {fileListName {}}} {
    set cmd [list exec svn diff]
    lappend cmd {*}[RevsToCmd $revs]
    lappend cmd {*}$files

    if {[catch {eval $cmd} res]} {
        tk_messageBox -icon error -title "SVN error" -message $res
        return ""
    }
    if {$fileListName ne ""} {
        upvar 1 $fileListName fileList
        set fileList {}
        # SVN will have lines like this to show files:
        #Index: dir1/f11
        foreach line [lsearch -all -inline -regexp [split $res \n] {^Index: }] {
            if {[regexp {Index: (.*)} $line -> fn]} {
                lappend fileList $fn
            }
        }
        set fileList [lsort -dictionary -unique $fileList]
    }

    return $res
}

proc eskil::rev::SVN::getChangedFiles {dir revs} {
    # Must call SVN in top dir to get full changeset
    GetTopDir $dir top tail
    set cmd [list execDir $top svn diff --summarize]
    lappend cmd {*}[RevsToCmd $revs]

    if {[catch {eval $cmd} res]} {
        tk_messageBox -icon error -title "SVN error" -message $res
        return ""
    }
    # Result is one file per line, with an info word before
    set files {}
460
461
462
463
464
465
466
467

468
469
470
471
472

473
474
475
476
477














478
479
480
481
482
483
484
475
476
477
478
479
480
481

482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513







-
+
-




+





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








    if {$old != ""} {
        cd $old
    }
}

# Get a HG patch
proc eskil::rev::HG::getPatch {revs {files {}}} {
proc eskil::rev::HG::getPatch {revs files {fileListName {}}} {
    # TODO: support files
    set cmd [list exec hg diff]
    foreach rev $revs {
        lappend cmd -r $rev
    }
    lappend cmd "--" {*}$files

    if {[catch {eval $cmd} res]} {
        tk_messageBox -icon error -title "HG error" -message $res
        return ""
    }
    if {$fileListName ne ""} {
        upvar 1 $fileListName fileList
        set fileList {}
        # HG will have lines like this to show files:
        #diff -r 533b1d848a1c dir1/f12
        #diff -r 0dba7b280f8f -r 2e84355cc419 f1
        foreach line [lsearch -all -inline -regexp [split $res \n] {^diff -}] {
            if {[regexp {diff (?:-r \w+\s+)*(.*)$} $line -> fn]} {
                lappend fileList $fn
            }
        }
        set fileList [lsort -dictionary -unique $fileList]
    }

    return $res
}

proc eskil::rev::HG::getChangedFiles {dir revs} {
    set cmd [list execDir $dir hg diff --stat]
    foreach rev $revs {
        lappend cmd -r $rev
524
525
526
527
528
529
530
531

532
533
534
535
536
537
538
553
554
555
556
557
558
559

560
561
562
563
564
565
566
567







-
+








    if {$old != ""} {
        cd $old
    }
}

# Get a BZR patch
proc eskil::rev::BZR::getPatch {revs {files {}}} {
proc eskil::rev::BZR::getPatch {revs files {fileListName {}}} {
    # TODO: support files
    set cmd [list exec bzr diff]
    if {[llength $revs] == 2} {
        lappend cmd -r [lindex $revs 0]..[lindex $revs 1]
    } elseif {[llength $revs] == 1} {
        lappend cmd -r [lindex $revs 0]
    }
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597







-
+







# Get an RCS revision
proc eskil::rev::RCS::get {filename outfile {rev {}}} {
    catch {exec co -p$rev [file nativename $filename] \
            > $outfile}
}

# Get a RCS patch
proc eskil::rev::RCS::getPatch {revs {files {}}} {
proc eskil::rev::RCS::getPatch {revs files {fileListName {}}} {
    # Not supported yet.
    return ""
}

proc eskil::rev::RCS::getChangedFiles {dir revs} {
    # Not supported yet.
    return ""
582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597
598
599
600
601
602
603
604













605
606
607
608
609
610
611
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653







-
+















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







# Add file to GIT index
proc eskil::rev::GIT::add {filename} {
    GetTopDir $filename dir tail
    catch {execDir $dir git add $tail}
}

# Get a GIT patch
proc eskil::rev::GIT::getPatch {revs {files {}}} {
proc eskil::rev::GIT::getPatch {revs files {fileListName {}}} {
    set cmd [list exec git diff -p]
    if {[llength $revs] == 0} {
        # Always default to HEAD to see changes regardless of index
        lappend cmd HEAD
    } else {
        foreach rev $revs {
            lappend cmd $rev
        }
    }
    lappend cmd "--" {*}$files

    if {[catch {eval $cmd} res]} {
        tk_messageBox -icon error -title "GIT error" -message $res
        return ""
    }
    if {$fileListName ne ""} {
        upvar 1 $fileListName fileList
        set fileList {}
        # GIT will have lines like this to show files:
        #diff --git a/dir1/f12 b/dir1/f12
        foreach line [lsearch -all -inline -regexp [split $res \n] {^diff -}] {
            if {[regexp { a/(.*) b/} $line -> fn]} {
                lappend fileList $fn
            }
        }
        set fileList [lsort -dictionary -unique $fileList]
    }
    
    return $res
}

# Get a GIT change set
proc eskil::rev::GIT::getChangedFiles {dir revs} {
    set cmd [list execDir $dir git diff --name-only]
    if {[llength $revs] == 0} {
638
639
640
641
642
643
644
645

646
647
648
649
650
651
652
653
654
655
656
657
658





659
660
661
662
663
664
665
666
667













668
669
670
671
672
673
674

675
676
677
678
679
680
681
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694
695





696
697
698
699
700









701
702
703
704
705
706
707
708
709
710
711
712
713






714
715
716
717
718
719
720
721
722







-
+








-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-

+







        catch {execDir $dir fossil finfo -p $tail > $outfile}
    } else {
        catch {execDir $dir fossil finfo -p $tail -r $rev > $outfile}
    }
}

# Get a FOSSIL patch
proc eskil::rev::FOSSIL::getPatch {revs {files {}}} {
proc eskil::rev::FOSSIL::getPatch {revs files {fileListName {}}} {
    set cmd [list exec fossil diff]

    if {[llength $revs] >= 1} {
        lappend cmd --from [lindex $revs 0]
    }
    if {[llength $revs] >= 2} {
        lappend cmd --to [lindex $revs 1]
    }
    if {[llength $files] > 0} {
        # Fossil diff only handles one file at a time.
        set res ""
        foreach file $files {
            set fcmd $cmd
    # Include added files contents
    lappend cmd -N

    lappend cmd {*}$files

            lappend fcmd $file
            if {[catch {eval $fcmd} fres]} {
                tk_messageBox -icon error -title "FOSSIL error" -message $fres
                return ""
            }
            # Fake the per-file rows
            append res "Index: $file\n==================================\n"
            append res $fres
        }
    if {[catch {eval $cmd} res]} {
        tk_messageBox -icon error -title "FOSSIL error" -message $res
        return ""
    }
    if {$fileListName ne ""} {
        upvar 1 $fileListName fileList
        set fileList {}
        # FOSSIL will have lines like this to show files:
        #Index: dir1/f11
        foreach line [lsearch -all -inline -regexp [split $res \n] {^Index: }] {
            if {[regexp {Index: (.*)} $line -> fn]} {
                lappend fileList $fn
            }
    } else {
        # Include added files contents
        lappend cmd -N
        if {[catch {eval $cmd} res]} {
            tk_messageBox -icon error -title "FOSSIL error" -message $res
            return ""
        }
        set fileList [lsort -dictionary -unique $fileList]
    }
    return $res
}

proc eskil::rev::FOSSIL::getChangedFiles {dir revs} {
    set cmd [list execDir $dir fossil diff]

707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
748
749
750
751
752
753
754

755
756
757
758
759
760
761
762







-
+







    if {[catch {exec cleartool get -to $outfile $filerev} msg]} {
        tk_messageBox -icon error -title "Cleartool error" -message $msg
        return
    }
}

# Get a CT patch
proc eskil::rev::CT::getPatch {revs {files {}}} {
proc eskil::rev::CT::getPatch {revs files {fileListName {}}} {
    # Not supported yet
    return ""
}

proc eskil::rev::CT::getChangedFiles {dir revs} {
    # Not supported yet
    return ""
1674
1675
1676
1677
1678
1679
1680

1681



1682
1683
1684
1685
1686
1687
1688
1715
1716
1717
1718
1719
1720
1721
1722

1723
1724
1725
1726
1727
1728
1729
1730
1731
1732







+
-
+
+
+







            $::widgets($top,commit) configure -state normal
        }
        if {[info commands eskil::rev::${type}::revertFile] ne ""} {
            $::widgets($top,revert) configure -state normal
        }
    }

    set fileList {}
    return [eskil::rev::${type}::getPatch $revs $files]
    set patch [eskil::rev::${type}::getPatch $revs $files fileList]
    set ::eskil($top,patchFilelist) $fileList
    return $patch
}

##############################################################################
# Utilities
##############################################################################

# Execute a command within a specific dir as pwd
1798
1799
1800
1801
1802
1803
1804

1805
1806
1807
1808
1809
1810
1811
1812
1813

1814
1815
1816
1817
1818
1819
1820
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857

1858
1859
1860
1861
1862
1863
1864
1865







+








-
+







    }

    set res [string trim $::eskil(logdialog)]
    set ::eskil(logdialog) $res

    set todo $postcmd
    if {[llength $postcmd] > 1} {
        # Look through checkbuttons
        set todo {}
        set t 0
        foreach fileName $postcmd {
            if {$::eskil($top,commit,fileselect$t)} {
                lappend todo $fileName
            }
            incr t
        }
        # None left means skip.
        # None left means ignore.
        if {[llength $todo] == 0} {
            return
        }
    }

    # Splash screen for visual feedback
    set now [clock clicks -milliseconds]