Eskil

Check-in [e22c3ec0ee]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Better visibility that commit happened.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e22c3ec0ee786f4ecf3b9cfef5c049c61b4459465dd0cc18684399790f156f24
User & Date: peter 2018-06-13 20:58:49
Context
2018-06-13
21:09
Bumped revision to 2.8.3 check-in: cdc0f1b1e1 user: peter tags: trunk
20:58
Better visibility that commit happened. check-in: e22c3ec0ee user: peter tags: trunk
2018-06-08
21:22
Update tutorial to match GUI changes. check-in: 623bcc4d80 user: peter tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Changes.




1
2
3
4
5
6
7



2018-06-05
 Working on shortcuts for preprocess dialog.

2018-05-14
 Added changeset tool to fourway,

2018-05-13
>
>
>







1
2
3
4
5
6
7
8
9
10
2018-06-13
 Better visibility that commit happened.

2018-06-05
 Working on shortcuts for preprocess dialog.

2018-05-14
 Added changeset tool to fourway,

2018-05-13

Changes to src/preprocess.tcl.

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    addBalloon $w.fb1.b1 "Add generic pattern"
    ttk::button $w.fb1.b2 -text "Add Subst" -command [list AddPrefRegsub $top $w Subst]
    addBalloon $w.fb1.b2 "Add using substitution shortcut"
    ttk::button $w.fb1.b3 -text "Add Prefix" -command [list AddPrefRegsub $top $w Prefix]
    addBalloon $w.fb1.b3 "Add using prefix shortcut"
    grid $w.fb1.b1 $w.fb1.b2 $w.fb1.b3 -sticky we -ipadx 5 -padx 3 -pady 3
    grid columnconfigure $w.fb1 all -uniform a
    grid anchor $w.fb1 w

    # Result example part
    if {![info exists ::eskil($top,prefregexa)]} {
        set ::eskil($top,prefregexa) \
                "An example TextString FOR_REGSUB /* Comment */"
        set ::eskil($top,prefregexa2) \
                "An example TextString FOR_REGSUB /* Comment */"







|







296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    addBalloon $w.fb1.b1 "Add generic pattern"
    ttk::button $w.fb1.b2 -text "Add Subst" -command [list AddPrefRegsub $top $w Subst]
    addBalloon $w.fb1.b2 "Add using substitution shortcut"
    ttk::button $w.fb1.b3 -text "Add Prefix" -command [list AddPrefRegsub $top $w Prefix]
    addBalloon $w.fb1.b3 "Add using prefix shortcut"
    grid $w.fb1.b1 $w.fb1.b2 $w.fb1.b3 -sticky we -ipadx 5 -padx 3 -pady 3
    grid columnconfigure $w.fb1 all -uniform a
    grid anchor $w.fb1 "w"

    # Result example part
    if {![info exists ::eskil($top,prefregexa)]} {
        set ::eskil($top,prefregexa) \
                "An example TextString FOR_REGSUB /* Comment */"
        set ::eskil($top,prefregexa2) \
                "An example TextString FOR_REGSUB /* Comment */"

Changes to src/rev.tcl.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
...
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
....
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
....
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245


1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265


1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292

1293
1294
1295
1296
1297


1298
1299
1300
1301
1302
1303
1304
1305
....
1306
1307
1308
1309
1310
1311
1312
1313


1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
....
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
....
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
....
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
....
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
....
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763




1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789



1790
1791
1792
1793
1794
1795
1796













1797





1798
1799
1800
1801
1802
1803
1804
1805
# If file is empty, check directory for control.
#
# Returns true if controlled or false if not.

# eskil::rev::XXX::ParseRevs {filename revs}
#
# Figure out revision from a list given by user
# 
# Returns a list of revisions to display.
#
# Filename may be empty, the rev corresponds to the working tree

# eskil::rev::XXX::get {filename outfile rev}
#
# Get a revision of a file and place it in outfile.
................................................................................
# Return revision list of a FOSSIL file
proc eskil::rev::FOSSIL::GetRevList {filename} {
    # Keep on current branch
    set x [execDir $filename fossil branch list]
    if { ! [regexp -line {^\* (.*)$} $x -> branch]} {
        set branch ""
    }
    
    # First, traverse timeline to get a set of ancestor checkins on the
    # current branch
    set x [execDir $filename fossil timeline ancestors current -t ci -n 5000]
    set ancestors {}
    set lines ""
    set currentArtefact ""
    foreach line [split $x \n] {
................................................................................
    foreach rev $revs {
        # Special cases that shortcuts to GIT special names
        if {$rev eq "_" || $rev eq "0"} {set rev HEAD}

        if {[string is integer -strict $rev] && $rev < 0} {
            # A negative integer rev is a relative rev
            set revList [eskil::rev::GIT::GetRevList $filename]
            
            set rev [lindex $revList [- $rev]]
            if {$rev eq ""} {
                set rev [lindex $revs end]
            }
        }
        # Let anything else through
        lappend result $rev
................................................................................
    set tail [string range $tail 1 end]
    set parts [file split $tail]
    set alt {}
    switch [lindex $parts 0] {
        trunk {
            lappend alt [file join [lreplace $parts 0 0 branches $rev]]
            lappend alt [file join [lreplace $parts 0 0 tags $rev]]
            if {$rev eq "trunk"} { 
                lappend alt [file join [lreplace $parts 0 0 trunk]]
            }
        }
        branches - tags {
            if {$rev eq "trunk"} { 
                lappend alt [file join [lreplace $parts 0 1 trunk]]
            }
            lappend alt [file join [lreplace $parts 0 1 branches $rev]]
            lappend alt [file join [lreplace $parts 0 1 tags $rev]]
        }
    }
    foreach tailAlt $alt {
................................................................................
proc eskil::rev::CVS::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        
    set logmsg [LogDialog $top $target]
    if {$logmsg eq ""} return

    set sts [catch {exec cvs -q commit -m $logmsg {*}$args} errmsg]
}

# Check in SVN controlled file
proc eskil::rev::SVN::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        


    set logmsg [LogDialog $top $target]
    if {$logmsg eq ""} return

    set sts [catch {exec svn -q commit -m $logmsg {*}$args} svnmsg]
    set svnmsg [string trim $svnmsg]
    if {$svnmsg ne ""} {
        tk_messageBox -icon error -title "SVN commit error" -message $svnmsg \
                -parent $top
    }
}

# Check in HG controlled file
proc eskil::rev::HG::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        


    set logmsg [LogDialog $top $target]
    if {$logmsg eq ""} return

    set sts [catch {exec hg -q commit -m $logmsg {*}$args} svnmsg]
    set svnmsg [string trim $svnmsg]
    if {$svnmsg ne ""} {
        tk_messageBox -icon error -title "HG commit error" -message $svnmsg \
                -parent $top
    }
}

# Check in GIT controlled file
proc eskil::rev::GIT::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        
    set logmsg [LogDialog $top $target]
    if {$logmsg eq ""} return

    if {[llength $args] == 0} {
        set sts [catch {exec git commit -a -m $logmsg} gitmsg]
    } else {
        set sts [catch {exec git commit -m $logmsg {*}$args} gitmsg]

    }
    set gitmsg [string trim $gitmsg]
    if {$sts} {
        tk_messageBox -icon error -title "GIT commit error" -message $gitmsg \
                -parent $top


    } elseif {[string match "*detached HEAD*" $gitmsg]} {
        # Make sure to make a detached HEAD commit visible.
        tk_messageBox -icon info -title "GIT commit message" -message $gitmsg \
                -parent $top
    }
}

# Check in Fossil controlled file
................................................................................
proc eskil::rev::FOSSIL::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        


    set logmsg [LogDialog $top $target]
    if {$logmsg eq ""} return

    set sts [catch {exec fossil commit -m $logmsg {*}$args} errmsg]
    if {$sts} {
        tk_messageBox -icon error -title "Fossil commit error" \
                -message $errmsg -parent $top
    }
}


# Revert SVN controlled file
proc eskil::rev::SVN::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    if {[llength $args] == 0} {
        set args "-R ."
    }
    set sts [catch {exec svn revert -q {*}$args} svnmsg]
................................................................................
proc eskil::rev::HG::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    if {[llength $args] == 0} {
        set args "--all"
    }
    set sts [catch {exec hg revert -q -C {*}$args} svnmsg]
................................................................................
proc eskil::rev::FOSSIL::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    set sts [catch {exec fossil revert {*}$args} errmsg]
    if {$sts} {
        tk_messageBox -icon error -title "Fossil revert error" \
                -message $errmsg -parent $top
................................................................................
proc eskil::rev::GIT::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }        
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    if {[llength $args] == 0} {
        set sts [catch {exec git checkout .} gitmsg]
    } else {
        set sts [catch {exec git checkout {*}$args} gitmsg]
................................................................................
    if {$file ne ""} {
        if {![file exists $file]} { return "" }

        if {[info exists cache($file)]} {
            return $cache($file)
        }
    }
    
    set searchlist [list $preference GIT FOSSIL HG BZR P4]
    foreach ns [namespace children eskil::rev] {
        lappend searchlist [namespace tail $ns]
    }
    foreach rev $searchlist {
        set result [eskil::rev::${rev}::detect $file]
        if {$result} {
................................................................................
    if {$penultimate eq "."} {
        return $last
    } else {
        return [file join $penultimate $last]
    }
}

# Dialog for log message
proc LogDialog {top target {clean 0}} {
    set w $top.logmsg
    destroy  $w
    toplevel $w -padx 3 -pady 3
    wm title $w "Commit log message for $target"

    set ::eskil($top,logdialogok) 0





    text $w.t -width 70 -height 10 -font myfont
    if {!$clean && [info exists ::eskil(logdialog)]} {
        $w.t insert end $::eskil(logdialog)
        $w.t tag add sel 1.0 end-1c
        $w.t mark set insert 1.0
    }

    ttk::button $w.ok -width 10 -text "Commit" -underline 1 \
            -command "set ::eskil($top,logdialogok) 1 ; \
                      set ::eskil(logdialog) \[$w.t get 1.0 end\] ; \
                      destroy $w"
    ttk::button $w.ca -width 10 -text "Cancel" -command "destroy $w" \
            -underline 0
    bind $w <Alt-o> [list $w.ok invoke]\;break
    bind $w <Alt-c> [list destroy $w]\;break
    bind $w <Key-Escape> [list destroy $w]\;break

    grid $w.t  - -sticky news -padx 3 -pady 3
    grid $w.ok $w.ca -padx 3 -pady 3
    grid columnconfigure $w $w.t -weight 1 -uniform a
    grid rowconfigure    $w $w.t -weight 1
    tkwait visibility $w
    focus -force $w.t
    tkwait window $w

    if {$::eskil($top,logdialogok)} {



        set res [string trim $::eskil(logdialog)]
        set ::eskil(logdialog) $res
        if {$res eq ""} {
            set res "No Log"
        }
    } else {
        set res ""













    }





    return $res
}

# Dialog for revert acknowledge
proc RevertDialog {top target} {
    set msg "Discard local changes for $target ?"
    set result [tk_messageBox -type okcancel -icon question -parent $top \
                        -title "Revert" -message $msg]







|







 







|







 







|







 







|




|







 







|
|
|
|
<










|
>
>
|
<
<
<
<
<
<
<
<










|
>
>
|
<
<
<
<
<
<
<
<










|
<
<
<

|

<
>

<
<
<
<
>
>
|







 







|
>
>
|
<
<
<
<
<
<
<











|







 







|







 







|







 







|







 







|







 







|
|







>
>
>
>

|








|












|

|
>
>
>
|
|
<
<
|
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
...
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
....
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
....
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247








1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261








1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272



1273
1274
1275

1276
1277




1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
....
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298







1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
....
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
....
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
....
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
....
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
....
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775


1776

1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
# If file is empty, check directory for control.
#
# Returns true if controlled or false if not.

# eskil::rev::XXX::ParseRevs {filename revs}
#
# Figure out revision from a list given by user
#
# Returns a list of revisions to display.
#
# Filename may be empty, the rev corresponds to the working tree

# eskil::rev::XXX::get {filename outfile rev}
#
# Get a revision of a file and place it in outfile.
................................................................................
# Return revision list of a FOSSIL file
proc eskil::rev::FOSSIL::GetRevList {filename} {
    # Keep on current branch
    set x [execDir $filename fossil branch list]
    if { ! [regexp -line {^\* (.*)$} $x -> branch]} {
        set branch ""
    }

    # First, traverse timeline to get a set of ancestor checkins on the
    # current branch
    set x [execDir $filename fossil timeline ancestors current -t ci -n 5000]
    set ancestors {}
    set lines ""
    set currentArtefact ""
    foreach line [split $x \n] {
................................................................................
    foreach rev $revs {
        # Special cases that shortcuts to GIT special names
        if {$rev eq "_" || $rev eq "0"} {set rev HEAD}

        if {[string is integer -strict $rev] && $rev < 0} {
            # A negative integer rev is a relative rev
            set revList [eskil::rev::GIT::GetRevList $filename]

            set rev [lindex $revList [- $rev]]
            if {$rev eq ""} {
                set rev [lindex $revs end]
            }
        }
        # Let anything else through
        lappend result $rev
................................................................................
    set tail [string range $tail 1 end]
    set parts [file split $tail]
    set alt {}
    switch [lindex $parts 0] {
        trunk {
            lappend alt [file join [lreplace $parts 0 0 branches $rev]]
            lappend alt [file join [lreplace $parts 0 0 tags $rev]]
            if {$rev eq "trunk"} {
                lappend alt [file join [lreplace $parts 0 0 trunk]]
            }
        }
        branches - tags {
            if {$rev eq "trunk"} {
                lappend alt [file join [lreplace $parts 0 1 trunk]]
            }
            lappend alt [file join [lreplace $parts 0 1 branches $rev]]
            lappend alt [file join [lreplace $parts 0 1 tags $rev]]
        }
    }
    foreach tailAlt $alt {
................................................................................
proc eskil::rev::CVS::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set precmd [list cvs -q commit -m]
    set postcmd $args
    CommitDialog $top $target CVS $precmd $postcmd

}

# Check in SVN controlled file
proc eskil::rev::SVN::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set precmd [list svn -q commit -m]
    set postcmd $args
    CommitDialog $top $target SVN $precmd $postcmd








}

# Check in HG controlled file
proc eskil::rev::HG::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set precmd [list hg -q commit -m]
    set postcmd $args
    CommitDialog $top $target HG $precmd $postcmd








}

# Check in GIT controlled file
proc eskil::rev::GIT::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }



    if {[llength $args] == 0} {
        set precmd [list git commit -a -m]
    } else {

        set precmd [list git commit -m]
    }




    set postcmd $args
    set gitmsg [CommitDialog $top $target GIT $precmd $postcmd 1]
    if {[string match "*detached HEAD*" $gitmsg]} {
        # Make sure to make a detached HEAD commit visible.
        tk_messageBox -icon info -title "GIT commit message" -message $gitmsg \
                -parent $top
    }
}

# Check in Fossil controlled file
................................................................................
proc eskil::rev::FOSSIL::commitFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set precmd [list fossil commit -m]
    set postcmd $args
    CommitDialog $top $target Fossil $precmd $postcmd 1







}


# Revert SVN controlled file
proc eskil::rev::SVN::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    if {[llength $args] == 0} {
        set args "-R ."
    }
    set sts [catch {exec svn revert -q {*}$args} svnmsg]
................................................................................
proc eskil::rev::HG::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    if {[llength $args] == 0} {
        set args "--all"
    }
    set sts [catch {exec hg revert -q -C {*}$args} svnmsg]
................................................................................
proc eskil::rev::FOSSIL::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    set sts [catch {exec fossil revert {*}$args} errmsg]
    if {$sts} {
        tk_messageBox -icon error -title "Fossil revert error" \
                -message $errmsg -parent $top
................................................................................
proc eskil::rev::GIT::revertFile {top args} {
    if {[llength $args] == 0} {
        set target all
    } elseif {[llength $args] == 1} {
        set target [file tail [lindex $args 0]]
    } else {
        set target "[file tail [lindex $args 0]] ..."
    }
    set ok [RevertDialog $top $target]
    if {$ok ne "ok"} return

    if {[llength $args] == 0} {
        set sts [catch {exec git checkout .} gitmsg]
    } else {
        set sts [catch {exec git checkout {*}$args} gitmsg]
................................................................................
    if {$file ne ""} {
        if {![file exists $file]} { return "" }

        if {[info exists cache($file)]} {
            return $cache($file)
        }
    }

    set searchlist [list $preference GIT FOSSIL HG BZR P4]
    foreach ns [namespace children eskil::rev] {
        lappend searchlist [namespace tail $ns]
    }
    foreach rev $searchlist {
        set result [eskil::rev::${rev}::detect $file]
        if {$result} {
................................................................................
    if {$penultimate eq "."} {
        return $last
    } else {
        return [file join $penultimate $last]
    }
}

# Dialog for commit, getting log message
proc CommitDialog {top target system precmd postcmd {useSts 0}} {
    set w $top.logmsg
    destroy  $w
    toplevel $w -padx 3 -pady 3
    wm title $w "Commit log message for $target"

    set ::eskil($top,logdialogok) 0

    # Dummy frame used for detecting closed window
    ttk::frame $w.dummy -width 10 -height 10
    place $w.dummy -x 0 -y 0

    text $w.t -width 70 -height 10 -font myfont
    if {[info exists ::eskil(logdialog)]} {
        $w.t insert end $::eskil(logdialog)
        $w.t tag add sel 1.0 end-1c
        $w.t mark set insert 1.0
    }

    ttk::button $w.ok -width 10 -text "Commit" -underline 1 \
            -command "set ::eskil($top,logdialogok) 1 ; \
                      set ::eskil(logdialog) \[$w.t get 1.0 end\] ; \
                      destroy $w.dummy"
    ttk::button $w.ca -width 10 -text "Cancel" -command "destroy $w" \
            -underline 0
    bind $w <Alt-o> [list $w.ok invoke]\;break
    bind $w <Alt-c> [list destroy $w]\;break
    bind $w <Key-Escape> [list destroy $w]\;break

    grid $w.t  - -sticky news -padx 3 -pady 3
    grid $w.ok $w.ca -padx 3 -pady 3
    grid columnconfigure $w $w.t -weight 1 -uniform a
    grid rowconfigure    $w $w.t -weight 1
    tkwait visibility $w
    focus -force $w.t
    tkwait window $w.dummy

    if {!$::eskil($top,logdialogok)} {
        return
    }

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




    # Splash screen for visual feedback
    set now [clock clicks -milliseconds]
    ttk::label $w.splash -text "Committing" -anchor center -font myfont
    place $w.splash -x 0 -y 0 -relwidth 1.0 -relheight 1.0
    update
    # Commit
    set cmd [list {*}$precmd $res {*}$postcmd]
    set sts [catch {exec {*}$cmd} msg]
    set msg [string trim $msg]
    if {($useSts && $sts) || (!$useSts && $msg ne "")} {
        destroy $w
        tk_messageBox -icon error -title "$system commit error" -message $msg \
                -parent $top
        return
    }
    # Keep it up for a decent length, regardless of commit delay
    while {abs([clock clicks -milliseconds] - $now) < 500} {
        after 100
    }
    destroy $w
    return $msg
}

# Dialog for revert acknowledge
proc RevertDialog {top target} {
    set msg "Discard local changes for $target ?"
    set result [tk_messageBox -type okcancel -icon question -parent $top \
                        -title "Revert" -message $msg]