Fossil Wrapper


fsl Cookbook

This is a gathering point for .fslrc snippets that do potentially useful things. It can be surfed for snippets to take out and use directly or just as inspiration for other functionality.

Initial workflow fix

One of the annoyances of Fossil is that the usual workflow can be a bit tedious and repetitive. The following interceptor adds a "cr:eate" command that solves this. Its command line is as follows:

fsl cr(eate) [password]

The interceptor does the following:

  1. Creates a new fossil repository in ~/Repositories named by the current working directory (assumed to be where the project will live). It gets its default settings from ~/Repositories/skeleton.fossil.
  2. Opens the newly-created repository.
  3. If the optional password is given, sets the password on the Fossil user matching the logged-in user.
  4. Opens a new branch named "development".
  5. Switches to that new branch.

interceptor cr:create {
    global tcl_platform

    set repodir [file join [file normalize ~] Repositories]
    set reponame [file join $repodir [file tail [pwd].fossil]]
    set skeleton [file join $repodir skeleton.fossil]

    set user $tcl_platform(user)
    set password [lindex $params 1]

    fossil new $reponame --template $skeleton
    fossil open $reponame

    if {$password != ""} {
        fossil user password $user $password

    fossil branch new development trunk
    fossil update development

    return {}

On 2012-12-29 13:53:21 UTC michael added:

Making things garish

You can do a lot of stuff with filters. Say, for example, that you want a busier timeline or leaves display. The following filter will give it to you:

filter fancy_timeline {leaves timeline} {
    if {[regexp "^=== .* ===" $line]} {
        return [coloured green $line]
    # Expressions to match:
    set artifact_rx  {\[([a-f\d]{4})([^\]]*)\]}
    set date_rx      {^\d\d:\d\d:\d\d}
    set current_rx   {\*CURRENT\*}
    set branch_rx    {\*(MERGE|BRANCH)\*}
    # Colour the output (repeated substitutions on $line):
    set line [regsub -all $artifact_rx $line\
        [format {[%s%s]}\
            [coloured yellow [display bright {\1}]]\
            [coloured yellow {\2}]]]
    set line [regsub $date_rx    $line [coloured blue &]]
    set line [regsub $current_rx $line [display reversed &]]
    set line [regsub $branch_rx  $line [display bright &]]
    # Values for user and tags may wrap, so left uncoloured:
    regsub -all {(user:|tags:)\s+} $line [coloured yellow &]

Be sure to also disable log_entry otherwise both filters will be triggered. To do so either comment out log_entry or clear its command list,

filter log_entry {} {

This is what it looks like:

On 2012-12-30 14:16:50 UTC michael added:

Cloning workflow fix

This interceptor is the other half of the pair begun with the "Initial workflow fix" interceptor. Its command line is:

fsl dup(licate) url [password]

The interceptor works as follows:

  1. Clones the repository at the provided URL into ~/Repositories named by the current working directory.
  2. Opens the newly-cloned repository into the current working directory.
  3. Adds the current logged-in user to the user list.
  4. If the optional password is given, the user's password is changed to that.

interceptor dup:duplicate {
    global tcl_platform

    set repodir  [file join [file normalize ~] Repositories]
    set reponame [file join $repodir [file tail [pwd].fossil]]

    set user     $tcl_platform(user)
    set url      [lindex $params 1]
    set password [lindex $params 2]

    fossil clone $url $reponame
    fossil open $reponame

    if {$password != ""} {
        fossil user password $user $password

    return {}

On 2013-01-17 09:29:19 UTC michael added:

Purging MISSING files

This combination of an alias, a filter and an interceptor will purge all MISSING files from your repository. Useful for those cases where you forget to fossil rm before using the real rm.

# fsl purge
# Purge all files flagged as "MISSING".
alias capture_changes changes

filter captured_changes {capture_changes} {
    variable captured
    lappend captured $line
    return {}

interceptor purge {
    variable captured {}
    fossil capture_changes
    foreach line $captured {
        if [string match MISSING* $line] {
            regsub ^MISSING $line {} file
            fossil rm [string trim $file]
    return {}

On 2013-07-03 21:33:51 UTC marc added:

Colouring the current branch

A simple filter for colouring the current branch:

filter branch {br:branch} {
    switch -regexp $line {
        {^\*}   { coloured yellow $line }
        default {             set  line }


On 2014-05-07 10:35:18 UTC fifr added:

Interactive commit: record

During development it is sometimes convenient to be able to commit only some of the changes in the current working directory. Fossil allows to select some files to be included in the next commit, but it is not possible to select only few changes in one file. Note that it is arguable whether such partial commits are a good thing or not because they encourage the creation of checkins with untested code.

This modification adds a record command, which mimics Mercurial's record extension. It allows to interactively select hunks to be included in the next commit.

fsl record some/files/*

The latest version of a fslrc file with this code is in the record branch and can be found here (just drop the code into your .fslrc file).

On 2016-04-24 16:18:19 UTC marc added:

Controlling autosync

Useful aliases for controlling autosync behaviour:

alias live  {set autosync on}
alias local {set autosync off}


$ fsl local
# offline for a while...
$ fsl live

On 2019-12-12 19:06:05 UTC marc added:

Quick snapshots

To quickly snapshot the working tree (without reverting anything),

interceptor snap {
  set now [clock format [clock seconds]]
  fossil stash snapshot -m "fsl snap @ $now"
  return {}  


$ fsl snap
$ fsl stash ls
    1: [06a31756cc58f2] on 2019-12-12 19:05:22
       fsl snap @ Thu Dec 12 11:05:22 PST 2019

(inspired by Stephan Beal's fsnap alias).