An alternative to git, fossil a quick review

First a disclaimer, after reviewing fossil I will be remaining with git as my source control system. From a command line perspective it provides no benefits to me over git and while it can sync changes made in fossil to a remote git (ie:github) repository it cannot detect/sync changes made to the remote git repository so does not syncronise the other way. As I use multiple machines to work with my github repository plus require the use of github as it is my ‘offsite backup’ for source code that makes it not suitable for me.

If you intend to replace git completely and do not use github or any local git repository it can provide you the same functionality as git, in that it also is a distributed version control system that allows pulling and pushing against remote fossil repositories. One advantage over git is that it is simple to create your own remote repository (in theory); it does however not have any external free storage repository such as a github equivalent so you must manage your own repositories (and probably lose everything if you are just using it for small development projects and have no external backup source).

It should also be noted that fossil runs on multiple platforms wheras git is only for Linux servers, so if you are developing on multiple platforms you could store all projects being managed on a single webserver hosting all the project repositories.

For migration it is possible to convert project repositories between fossil and git formats with simple export/import commands, I have an example of moving a git application to fossil later in the post.

The fossil application and documentation is available at https://fossil-scm.org/fossil/doc/trunk/www/index.wiki.

It should be noted that fossil provides many additional features over git on a per-project basis such as a WIKI and problem ticketing system for each individual fossil project. While this may be of benefit if you only have one application to manage in an environment where there is more than one application an external global ticketing system is obviously a better option; and I would assume all WIKI content would be lost if you converted from fossil to git although if you chose to stick with fossil it is obviously useful.

It should also be noted that I have been completely unable to get the ‘fossil push’ operation to work.

Interestingly if you are not at all interested in source code management but are looking for a help-desk type problem system fossils built in ticketing system user forum, wiki and tech note features along with it’s requirement that users be specifically added for update access may make it a perfectly useful problem management system.

The major differences between git and fossil

A major difference between git and fossil is that git uses the Linux host filesystem for file archiving and versioning, fossil uses SQLite databases for each project, as fossil was written to support SQLite development. While some people may say this makes it easier to move development from one machine to another simply by scp’ing the one SQLite database file containing the project I see no real benefit over a simple ‘git export’, scp and ‘git import’ to move a git project.

Another major difference between git and fossil is that git is pretty much open on who can make changes available encouraging contributers, fossil works in reverse permitting only trusted users to make changes so for each project you must create/authourise users.

Fossil also provides on a per-project basis a WIKI, Ticketing system, user forum and tech-note features al contained witrhin the same fossil binary that provides the command line interface to the repositories.

The basic source versioning funtions

There will be a learning curve in switching from git to fossil as while the
commands are similar they are not identical, so git users will be extremely frustrated in switching to fossil as commands ‘almost work’ but need tweaking.

Also frustrating is that fossil has an autocommit feature that will attempt to syncronise commits with the upstream repository whenever a local commit is made. While this is a good idea as it ensures everybosy is wotrking with the latest merged copy it will cause commit errors for users if they have not been configured properly, as seen below.

Autosync:  http://localhost/cgi-bin/fossil.sh/mvs38j_utils
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, sent: 439  received: 824  ip: 127.0.0.1
empty check-in comment.  continue (y/N)? y
New_Version: f691c302f1b2b0dedfd4cd60bd91a965dc83ce84aaea86e705b24adcb7887cd9
Autosync:  http://localhost/cgi-bin/fossil.sh/mvs38j_utils
Round-trips: 1   Artifacts sent: 2  received: 0
Sync done, sent: 1142  received: 859  ip: 127.0.0.1
Warning: The check-in was successful and is saved locally but you
         are not authorized to push the changes back to the server
         at http://localhost/cgi-bin/fossil.sh/mvs38j_utils

The issue with remote authentication to the fossil remote repository is mentioned quite often in this post so read on.

Both git and fossil support the normal versioning and branching features needed by a version control system. For use as a local machine versioning application they provide similar features.

Remote repositories

Obviously a source management system these days is only useful if source being worked on by multiple people can be consolidated in a central repository.

Unlike the complexity of git it is simple to create a remote repository using fossil as if you have a webserver running already it can be easily configured to run the fossil binary as a CGI interface to provide access to one or multiple repositories. The fossil binary can also run as a server to provide remote access to a single repository.

Note: for local use you can also use the ‘fossil ui’ command will launch a web browser to access web features for a repository on the local machine, if your local machine is running a GUI desktop of course which most development environments will not be.

I chose the CGI method as I had a working apache webserver and it allows multiple projects to be available. An example on how I set that up is at the end of this post.

The main difference between running fossil as a server or a CGI script refering to a single repository and my chosen method of using CGI to provide multiple repositories is simply that a project name must be appended to the remote URL. In the clone example below if the fossil server or a CGI script refering to a repository is used you would use the first command below, if using CGI and specifying a path to multiple repositories you would use the second command to identify the repository.

fossil clone http://localhost/cgi-bin/fossil.sh mvs38j_utils.fossil
fossil clone http://localhost/cgi-bin/fossil.sh/mvs38j_utils mvs38j_utils.fossil

Clone a repository

One thing is important to note when cloning a repository, the project id and admin user password is changed for the local copy.

[mark@vosprey3 temp]$ /home/fossil/fossil clone http://localhost/cgi-bin/fossil.sh/mvs38j_utils mvs38j_utils.fossil
Round-trips: 2   Artifacts sent: 0  received: 181
Clone done, sent: 548  received: 652209  ip: 127.0.0.1
Rebuilding repository meta-data...
  100.0% complete...
Extra delta compression... 
Vacuuming the database... 
project-id: f51c618d56d51898d27f0f46225829bf32931c73
server-id:  6472f0d2048663b39577dddb4ddc8c70c35a3852
admin-user: mark (password is "fAXrZB4vdP")

Another thing to note is that the change seems to serve no purpose other than to obscure the actual password used on the fossil remote repository, no password is not needed to open, branch or coomit to the local copy.

What is cloned is the SQLite database itself rather than a filesystem tree git users are used to. A ‘fossil open’ or ‘fossil branch’ of the local copy from a different work directory is needed to access the files within the repository.

[mark@vosprey3 temp]$ ls
mvs38j_utils.fossil

Pull from the remote repository

You cannot ‘pull’ a remote repository unless you have cloned it to a local copy first. Or createing an new empty project to pull into may work but I have not tried that, either way an extra step.

[mark@vosprey3 temp]$ /home/fossil/fossil pull http://localhost/cgi-bin/fossil.sh/mvs38j_utils -R mvs38j_utils.fossil
repository does not exist or is in an unreadable directory: mvs38j_utils.fossil

After a clone it is fine.

[mark@vosprey3 temp]$ /home/fossil/fossil clone http://localhost/cgi-bin/fossil.sh/mvs38j_utils mvs38j_utils.fossil
Round-trips: 2   Artifacts sent: 0  received: 181
Clone done, sent: 548  received: 652209  ip: 127.0.0.1
Rebuilding repository meta-data...
  100.0% complete...
Extra delta compression... 
Vacuuming the database... 
project-id: f51c618d56d51898d27f0f46225829bf32931c73
server-id:  e1f90ed7c925f8da14a0a8ce997dbe28eb46138b
admin-user: mark (password is "r4Fg2wbiTW")

[mark@vosprey3 temp]$ /home/fossil/fossil pull http://localhost/cgi-bin/fossil.sh/mvs38j_utils -R mvs38j_utils.fossil
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, sent: 322  received: 824  ip: 127.0.0.1
[mark@vosprey3 temp]$ 

Push to the remote repository

Does not appear to be possible to push to the source repository.

In the repository configuration on the remote server ‘Allow HTTP_AUTHENTICATION authentication’ has been set as permitted, however using no authority info, using the remote repository setup user/password, and using the local copy user/password all fail to push to the remote repository.

Also in the user configuration on the remote server side my userid was given access to every privalege (every checkbox was checked).

[mark@vosprey3 temp]$ /home/fossil/fossil push http://localhost/cgi-bin/fossil.sh/mvs38j_utils -R mvs38j_utils.fossil
Round-trips: 1   Artifacts sent: 0  received: 0
Error: not authorized to write
Round-trips: 1   Artifacts sent: 0  received: 0
Push done, sent: 780  received: 391  ip: 127.0.0.1

[mark@vosprey3 temp]$ /home/fossil/fossil push http://localhost/cgi-bin/fossil.sh/mvs38j_utils -R mvs38j_utils.fossil -B mark:LhikpKwBeP
Round-trips: 1   Artifacts sent: 0  received: 0
Error: not authorized to write
Round-trips: 1   Artifacts sent: 0  received: 0
Push done, sent: 824  received: 391  ip: 127.0.0.1

[mark@vosprey3 temp]$ /home/fossil/fossil push http://localhost/cgi-bin/fossil.sh/mvs38j_utils -R mvs38j_utils.fossil -B mark:r4Fg2wbiTW
Round-trips: 1   Artifacts sent: 0  received: 0
Error: not authorized to write
Round-trips: 1   Artifacts sent: 0  received: 0
Push done, sent: 824  received: 391  ip: 127.0.0.1
[mark@vosprey3 temp]$

Obviously this is a show stopper. Just as obviously there must be a way to do it but the documentation is not clear.

Migrating a git project to a fossil project

That is covered quite well at https://fossil-scm.org/home/doc/trunk/www/inout.wiki.


Fossil has the ability to import and export repositories from and to Git. And since most other version control systems will also import/export from Git, that means that you can import/export a Fossil repository to most version control systems using Git as an intermediary.

Below is how simple it is, I exported one git project, scp’ed the output to a machine with fossil on it, and imported it. It is that simple to move a git project to a fossil project. Not only managed source is imported but also a full checkin/change-history.

[mark@phoenix mvs38j_utils]$ git fast-export --all > /home/mark/mvs38j_utils.git.data
[mark@phoenix mvs38j_utils]$ scp /home/mark/mvs38j_utils.git.data mark@vosprey3:/home/mark
[mark@vosprey3 fossil]$ cat ~/mvs38j_utils.git.data | ./fossil import --git mvs38j_utils.fossil
Rebuilding repository meta-data...
  100.0% complete...
Vacuuming... ok
project-id: f51c618d56d51898d27f0f46225829bf32931c73
server-id:  24bc9ec6173188540a5598e64c2ce0d548177456
admin-user: mark (password is "LhikpKwBeP")
[mark@vosprey3 fossil]$ 

The admin-user/password combination can be used to login to the fossil web interface whether by fossil ui if you are on a desktop of via the CGI scripts if you have fossil on a headless webserver to perform further customisation for the project. This should be such things as creating a home page for the application (which is a WIKI page with the same name as your project), customising server settings and users etc.

Integrating fossil into an existing WebServer

I created a new directory specifically for fossil as /home/fossil. I did not create a new fossil user as of course it is the apache user that needs access to the files; and the directory could be placed anywhere apache has full access to. It should also be noted that should you have any users on the server that need access to work with the project on the server itself they need full access. I also placed the fossil binary in that directory.

Using /home/fossil as a directory this is how I set it up under apache. Note that xxx.fossil files need to be created for projects iin that directory, whether as empty fossil created projects or imported projects from git as discussed earlier.

mkdir /home/fossil
chmod 777 /home/fossil
touch /home/fossil/fossil_errors.log
chmod 666 /home/fossil/fossil_errors.log
cat << EOF > /var/www/cgi-bin/fossil.sh
#!/home/fossil/fossil
directory: /home/fossil
#repository: /home/fossil/mvs38j_utils.fossil
errorlog: /home/fossil/fossil_errors.log
notfound: http://mdickinson.dyndns.org/error_pages/no_fossil_repo.html
repolist
timeout: 120
setenv: SQLITE_TMPDIR=/var/tmp
setenv: TEMP=/var/tmp
setenv: FOSSIL_HOME=/home/fossil
EOF
chmod 755 /var/www/cgi-bin/fossil.sh

Key vaules to note are ‘repository’ plus the ‘directory’ and ‘repolist’ combination.

If ‘repository’ is used that is the only repostory available from this server, obviously that is fairly limiting. If the URL http://your.web.site/cgi-bin/fossil.sh is used that repository is presented. And that is also the URL for clone/pull/push to that one database.

However if ‘directory’ is used you may place many xxx.fossil databases in the directory and access them by name if you know the name and use a URL inclusing the name such as http://localhost/cgi-bin/fossil.sh/mvs38j_utils, browsing to the URL above without a database name would give an error. However if the ‘repolist’ value is also set then browsing to the URL above gives you a list of available databases you can use to select from.
For clone/pull/push you also need to provide the full database name you are using if using directory to host multiple repositories rather than repository to support only one repository.

Additional features fossil provides via it’s web interface

To be useful fossil will need to provide the web interface via the CGI script setup so multiple users can use the features. While I believe they would be available via the ‘fossul ui’ command that is for single user use; and as I am testing fossil on a headless server (no gui) I cannot test that.

Via the web interface that comes bundled with the fossil binary you also have access to a project specific WIKI, Ticketing system, user Forum and tech notes. It also provides nicely formatted ‘timelines’ of changes made throughout the application life.

All those features are specific to the project you are working with and part of the SQLite database for the project.

  • If you are working on more than one project it would therefore make sense to use at a minimum a sperate Ticketing system
  • or if you are a small shop you could use a fossil project as nothing but a Ticketing system as the WIKI, Tech notes, and Forum would provide additional benefits for that

Summary

fossil can replace all the git functions, plus provides additional features such as a WIKI, Forum and Ticketing system for each project. It is useful for sites that have their own source code repository stucture and do not reply on external repositories such as github or gitlab.

If you already use github or gitlab your choices are to convert the projects to fossil databases and move everything in-house, or continue to use git. I personally push to github from multiple sources so fossil is of no use to me as github must be the authoritive source rather than a local fossil repository in my environment.

Also as noted many times in this post I was unable to get the ‘push’ function to the remote fossil repository working at all. I am sure it is possible but as I will not be proceeding down the fossil path I will not be banging my head against this and will leave it up to you to try if you are interested in trying fossil.

About mark

At work, been working on Tandems for around 30yrs (programming + sysadmin), plus AIX and Solaris sysadmin also thrown in during the last 20yrs; also about 5yrs on MVS (mainly operations and automation but also smp/e work). At home I have been using linux for decades. Programming background is commercially in TAL/COBOL/SCOBOL/C(Tandem); 370 assembler(MVS); C, perl and shell scripting in *nix; and Microsoft Macro Assembler(windows).
This entry was posted in Unix. Bookmark the permalink.