Fossil Book

Documentation
Login

Multiple user

Introduction

In the previous chapter I went through using Fossil with just one user (me). In this chapter we will get into using it with multiple users. Thanks to Fossil's distributed design once the set up is done using it is not much different than the single user case with Fossil managing automatically the multiple user details.

Setup

In the previous chapter the Fossil repository was a file on our system and we did commits to it and pulled copies of the source from it. Fossil is a distributed source control system; what this means is that there is a master repository in a place that all users can access. Each user has their own "cloned" copy of the repository and Fossil will automatically synchronize the users repository with the master. From a each user's perspective you have your local repository and work with it using the same commands shown in Chapter [sec:Single-User-Fossil]. It's just that now Fossil will keep your repository in sync with the master.

Server

I have the FossilBook.fossil repository and now have to put it in place so multiple users can access it. There are two ways, the first is using fossil's built in webserver to host the file and the second is using the operating systems supported web server (if present) and a cgi type access.

Self hosted

This is quite simply the easiest way to do it. The downside is that you are responsible for keeping the machine available and the webserver up. That is, don't turn the machine off when you quit for the day or some other user is going to be upset. All I have to do is this:

[Pandora-2:/Users/jschimpf/Public] jim% cd FOSSIL/

This is on UNIX system, the "&" at then end of the second line runs the fossil webserver in the background. If I know this machine has an IP address of 192.168.1.200 then from any other machine in the network I can say:

http://192.168.1.200:8081 to the browser and I can access the Fossil web server.

As you can see this is simple and works on any system that runs Fossil. As long as you carefully make sure it's always running and available for others this can be a very easy way to make the master repository available.

The problems with this method are:

  1. If you have multiple repositories you have to use the server not the ui command, have all your repositories in the same directory, and have them all use the extension .fossil.

  2. If the machine goes off line (i.e. for OS update) or other reason it might not automatically restart the Fossil servers.

  3. Backup of the repositories might be not be done.

This method does work, and if you only have one repository and a diligent owner of the master machine, it will work and work well.

Server hosted

If you have a server type machine available (i.e., a Linux or UNIX box) that is running Apache or a Windows machine running IIS you can let it be the webserver for your repository. This has a number of advantages: this machine will be up all the time, it will probably be automatically backed up, and it can easily support multiple Fossil repositories.

I am not going into how to set up the webserver or how to enable (Common Gateway Interface) CGI. See the following sites.

If you are not in control of the webserver you will need the help of the server admin to enable CGI and to copy your CGI scripts to correct location.

CGI Script for hosted server

If we assume an Apache server and, in my case, the cgi directory path is /Library/Webserver/CGI-Executables, then we have to write a script of the form:

#!<Fossil executable location> repository: <Fossil repository location>

and put it into the cgi script directory. I have put my Fossil executable into /usr/local/bin and I am putting my Fossil shared repository into /Users/Shared/FOSSIL. My script then becomes:

#!/usr/local/bin/fossil # Put the book repository on the web repository: /Users/Shared/FOSSIL/Fossilbook.fossil

After making the script I then copy it to the CGI directory and allow anyone to execute it.

sudo cp Book.cgi /Library/Webserver/CGI-Executables/Book.cgi

Test the setup

If all is in place then I should be able to access the webserver and get to this: Web access to Fossil CGI hosted site

User accounts

Serving a repository, either self hosting or the more complicated CGI method gets you to the same place as shown in Figure [fig:Web-access-to]. Now I have to set up user accounts for the other contributors to this book. Remember Fossil has automatically created an Anonymous user (see Figure [fig:User-Configuration]) thus others can access the site in a limited way, that is they can download the book but cannot commit changes. In this case I want to create a new account (Marilyn) that can make changes and commit changes as she is my editor.

To accomplish all this first I have to login by going to the log in page and entering my ID (jim) and my password. Now since I'm super-user I then go back to the User-Configuration page, Figure [fig:User-Configuration] and add a new user:

New Editor user

Since she is going to be an editor, this will be similar to a developer if we were doing code, so I picked the Developer privilege level. This way she can get the repository, check-in, check-out, and write and update tickets. I also added the attachments since she might need that to put on an image or other comment on actions she is doing. I also gave her a password so her access can be secured.

I could add other users at this point but don't need any others for this project, but you can see how easily this can be done. When you assign the user privileges just read carefully and don't give them any more than you think they need. If they have problems, you can easily modify their account in the future.

Multiple user operation

With the server set up and the user established the next thing to do is clone the repository. That is make copy from the webserver repository to my local machine. Once that is done this local repository uses the same commands and is very much like single user use discussed in Section [sec:Single-User-Fossil]. Fossil will synchronize your local repository with the one on the server.

Cloning

To clone a Fossil repository you have to know four things:

  1. It's web address, for our repository it is http://pandora.dyn-o-saur.com:8080/cgi-bin/Book.cgi

  2. Your account name in my case it's jim

  3. Your password (which I'm keeping to myself thank you...)

  4. The local name of the repository, in this case I'm calling it Fossilbook.fossil

You then go to where you want to keep the Repository (in my case the FOSSIL directory) and use the clone command:

[Pandora-2:jschimpf/Public/FOSSIL]{} fossil clone http://jim:<passwd>@pandora.dyn-o-saur.com:8080/cgi-bin/Book.cgi FossilBook.fossil

At this point I can go through the steps outlined in Section [sec:Single-User-Fossil] to set my user password and then open the Fossil Repository on a working directory.

Now that I've moved everything to the new cloned repository I do a check in a the end of the day which looks like this:

[Pandora-2:jschimpf/Public/FossilBook] jim% fossil commit -m "Moved to clone repository"

As you see the files were committed locally and then the local repository was automatically synchronized with the repository on the server.

Keeping in sync

After doing all the setup described above I now have a distributed source control system. My co-worker, Marilyn has also cloned the repository and begun work. She is editing the book correcting my clumsy phrasing and fixing spelling mistakes. She is working independently and on the same files I use. We must use Fossil to prevent us from both modifying FossilBook.lyx but in different ways. Remember Fossil has no file locking, there is nothing to prevent her from editing and changing the file while I work on it.

This is where we both must follow procedures to prevent this sort of problem. Even though she edits files I cannot see the changes till they are committed. Two different versions of the same file won't be a problem till I try to commit with my version and her version is in the current leaf.

There are two problems:

  1. Before I do any work I must be sure I have the current versions of all the files.

  2. When I commit I must make sure what I am committing has only my changes and is not stepping on changes she has done.

The first is pretty obvious, make sure you have the latest before you do anything. We do that with the update command. In Figure [fig:Cloned-repository-checkin] I had done my latest check in. Before starting any more work I should ensure that Marilyn hasn't checked in something else. I could check the timeline but instead I'll do an update to my repository and source files. When I do the update I specify it should be updated from the trunk. This ensures I get it from the latest and greatest not some branch.

[Pandora-2:jschimpf/Public/FossilBook] jim% fossil update trunk

Ah ha ! Marilyn has been at work and updated the book source and pdf. If I check the timeline from the webserver I see she has even documented it:

Now I know I have the current state of the world and I can proceed to add in new sections.

Complications

In[There-are-two] the second case is much harder. In this case I have diligently done my fossil update and started working. In the mean time Marilyn has also done her update and also started working. Now she is done and checks in her changes. I obviously don't know this since I am happily working on my changes. What happens next....

[Pandora-2:jschimpf/Public/FossilBook] jim%fossil commit -m "Commit that might fork"

Ah ha, that very thing has happened and fossil warned me that my copy of the file differs from the master copy. If I did a –force then the repository would generate a fork and Marilyn's future commits would be to her fork and my commits would be to mine. That would not be what we want since I want her to edit my copy of the book.

The next step would be to do as Fossil says and do an update. At this point you have to be careful since blindly updating the changed files could overwrite the stuff I've just done. So we do a trial update by using the -n and -v options to say "do a dry run" and show me the results.

[Pandora-2:jschimpf/Public/FossilBook] jim% fossil update -n -v

That's a little more than I wanted as you can see almost everything is UNCHANGED but it shows that fossilbook.lyx needs a MERGE and fossilbook.pdf needs an UPDATE. This is what I should expect, Marilyn has done edits to the fossilbook.lyx file and so have I so we have to merge the changes. But she has also updated the fossilbook.pdf which I have not. Before we go on if you are running on Linux or UNIX you can simplify this dry run by doing:

[Pandora-2:jschimpf/Public/FossilBook] jim%fossil update -n -v grep -v UNCHANGED

By using the pipe and grep I can eliminate all those extra UNCHANGED lines.

Fixing the update file

First we fix the easy file, the fossilbook.pdf I can just update by itself so it matches the current repository. It doesn't need merged so just replace it. Before I do that I have to look at the repository time line

I see that the current Leaf is [d44769cc23] and it is tagged as trunk. I want to update the fossilbook.pdf from there. So I say:

[Pandora-2:jschimpf/Public/FossilBook] jim%fossil update trunk fossilbook.pdf

and it's done.

Fixing the merge file

We can use the tools built into Fossil. In this case noticing that commit will cause a fork Jim will use the -force option to cause the fork and will handle the merge later.

~/Profile/Ratte/data/organize/fossil-w32/fossil-book>fossil commit -m "adding some changes of jim"

Now the timeline looks like:

To remove this fork (i.e. get the changes Marilyn did into the trunk) we use the Fossil merge command. We can use the merge because fossilbook.lyx is a text file and the merge markers are designed to work with text files. If it was a binary file we might have to use an external file or copy and paste between the two file versions using the handler program for the file.

~/Profile/Ratte/data/organize/fossil-w32/fossil-book>fossil merge a91582b699

Looking at the file (fossilbook.lyx) in a text editor (not LyX) we find:

>>>>>>> BEGIN MERGE CONFLICT

After the commit the timeline shows how the merge brought the fork back into the main trunk. Marilyn will then have to update to this new trunk. (See Section [sub:Updating-by-others])