# Version Control Systems: Fossil Part I

• Tutorial
Greetings, colleagues!

Relatively recently, a survey was published here on the version control systems used. As expected, Git won by a wide margin, and Fossil was not even included in the list, only flashed a couple of times in the comments. A search in Habr showed that almost nothing was written about Fossil here. Therefore, I decided to publish this article - especially since the Russian-language information about Fossil is extremely scarce and monotonous.

Over the years of participation in open source development, I had the opportunity to use CVS, Subversion and Git, but I did not use the version control system for personal and work-related projects, until I met Fossil through a random link. Immediately hooked on the fact that you just need to download and copy to a suitable place, one - the only executable file. If so simple, why not give it a try? I also liked that the entire repository is also one file (SQLite database), which you can simply copy to take home or install it on another computer at work. I generally like the minimalist approach - maybe that’s why the hand didn’t rise to put something like Subversion for a team of 3-4 people.

As it turned out, Fossil is a completely “adult” system, not inferior in terms of basic functionality to its more well-known competitors. As a solid bonus, we have here a web interface, a bug tracking system and Wiki, and error notifications and wiki pages are in the same repository where the project files are also under the control of the version control system, etc. e. their changes are also tracked. In the process of operation and as the documentation was studied, even small but pleasant “goodies” were revealed that added confidence in the correctness of the choice made. I want to emphasize right away: rightness for me. Everyone has different requirements, different habits, someone else is more suitable for something else. For me, Fossil is a perfectly suitable, to say the least, solution.

Fossil Installation
So, go to http://www.fossil-scm.org/download.html and download the package that corresponds to our operating system. Unpack the executable file located somewhere, from where it will then be more convenient to run it, preferably in a directory accessible by SET PATH. Everything, the system is ready to work.

Create and configure a repository
Further, for definiteness, we will proceed from the assumption that we have Windows. Also, for definiteness, we assume that all of our repositories will be stored in a separate directory c: \ fossil, although, of course, you can not allocate any separate space for them, but place them directly next to the files that we give control Fossil. Next, suppose we have a Castle project, whose sources located in c: \ projects \ castle \ source \, we want to put under Fossil control - we will call them working files, and the source directory will be the working directory. And finally, create an empty castle.fossil repository for these sources:

fossil new c:\fossil\castle.fossil

Fossil will create a castle.fossil file and tell us the administrator name (usually the username under which you are logged into the OS) and password. Fossil is generally quite "talkative" and his messages must be read; important information may be contained there. As you already understood, all this happens in the console, so to use Fossil it is advisable to have command line skills and also be familiar with the English language - maybe I searched poorly, but I did not find any mention of internationalization.
The next step is to go to the c: \ projects \ castle directory and open the created repository:

c:
cd \projects\castle
fossil open c:\fossil\castle.fossil

Most Fossil operations are performed on an open repository, so this should be done immediately after creation. But to close it ( fossil close ) hardly makes sense - except after the completion of the project. The fossil open command creates a database service file in the current directory, its name may depend on the version of Fossil and on the OS - under Windows it is _FOSSIL_. This file stores information about the open repository and tracks changes in the files. Please note that before opening the repository, I went to the directory parent to the worker. This is important: the repository must be open either in the working directory or in one of the parent (at any level of the tree), otherwise Fossil will refuse to add files from the working directory to the repository.
In fact, fossil open not only creates a service file, but also checks the correspondence between files in the working directory and in the repository, and if any file from the repository is not in the working directory, or differs from it, it overwrites the file in the working directory from the repository (after warning all / yes / no). But since our repository is empty so far, nothing of the kind happens.

Before adding files to the repository, I would advise you to pre-configure something. There are two ways to do this.
1) From the console using the fossil settings command :

fossil settings crnl-glob '*'
fossil settings encoding-glob '*'

Setting crnl-glob to '*' (any) disables checking the characters of the end of the line, encoding-glob - checking the encoding of your files. If this is not done, and your files use a standard Windows CRNL sequence or encoding other than UTF-8, then Fossil will issue a warning and will require confirmation during the commit operation . In addition, it is advisable to specify a list of file masks that may be present in your working directory, but should not be included in the repository - object modules, executable files, etc., for example:

fossil settings ignore-glob '*.o,*.obj,*.exe,*.bak,*.log'

You can add the --global option to the fossil settings command - in this case this parameter will be set globally for all repositories on this computer. By the way, if the set value is not specified, then the fossil settings command will return the current value of the parameter in response, and if you do not specify the parameter name, we will get a list of all the preset parameters and their values.

2) The second way to set parameters - using the graphical interface:

fossil ui

As a result of this command, the Fossil web server will be launched, in this case the local one (the default port is 8080, you can specify another option --port) and the browser will use the URL 127.0.0.1:8080. To set the parameters, open the admin menu item, then settings and change crnl-glob, encoding-glob and ignore-glob there. At the same time, you can go into admin / configuration - set the name of the project and in admin / users - change your password.

Well, finally, add the files with the add command and send it to the repository with the commit command :

fossil add source
fossil commit -m "Initial commit"

fossil add .
Adds all files from the current directory and subdirectories.

Now that the repository is open and the files have been added to it, that is, put under the control of Fossil, you can actually continue work on the project. We write programs, articles, books, with each important change we send it to the repository - we make commit , accompanied by a meaningful comment:

fossil commit -m "Another brick in the wall"

Here are some more commands to delete / move / add files:

fossil rm source\wall\brick.c
Delete brick.c from the repository. In this case, all previous versions of this file remain in the repository, it is simply marked as deleted and its further changes in the repository are not fixed. This file is not deleted from the working directory - if necessary, we must do this ourselves.

fossil mv source\bridge\item* source\wall\
We move files with the item * mask from one directory to another. Note that Fossil does not move files in the working directory itself, we need to do this by hand.

fossil addremove
We add to the repository files from the working directory that are not in the repository (that is, a list of which the fossil extras command gives ) and delete files previously deleted from the working directory from the repository.

And a few commands that provide information about the repository and individual files:

fossil ls source\wall
We list the files from the source \ wall directory located in the repository, the -v parameter adds a column with the file status (EDITED, UNCHANGED), the --age parameter adds the last commit time for each file.

fossil status
We look at the current state of the repository.

fossil changes
A list of files changed since the last commit is displayed .

fossil extras
We display a list of "extra" files - those that are present in the working directory but are not included in the repository.

Commands for working with file versions - viewing changes, reverting

fossil timeline
fossil timeline after 2014-09-01
fossil timeline before 2014-07-15

We display the history of changes in the repository, the -v option adds to the output a list of files affected by each change. Using -t, you can specify what kind of changes should be output: -t ci - in files, -te - in events, -tt - in tickets, -tw - in wiki.

fossil finfo source\wall\brick.c
By default - display the history of the brick.c file changes. If the -s parameter is specified , then brief information about the file, if -p displays the contents of the file, and if, in addition to -p, the version identifier ( -r VERSION ) is also specified, the specified version of the file is displayed.

File version identifier is an important concept that should be discussed in more detail; it is used in many commands where you need to do something with a specific revision of a file or the entire repository. The following methods for identifying a version exist:
• SHA-1 hash
• label name (tag)
• timestamp - creation date and time
• distinguished names: tip, current, next, previous or prev

Each element in the Fossil repository — file versions, tickets, wiki pages, etc. — has a unique identifier, a 40-digit hash calculated using SHA-1. Since entering all 40 characters in a command is not very convenient, you can limit yourself to a few (at least 4) first characters. So, the first way to identify the version of the file is the initial fragment of the hash. Another way is the file creation date and time recorded in one of the formats: YYYY-MM-DD, YYYY-MM-DD HH: MM, YYYY-MM-DD HH: MM: SS. See here for more details .

fossil diff source\wall\brick.c
fossil diff --from VERSION1 --to VERSION2 source\wall\brick.c
fossil diff --from previous --to current source\wall\brick.c
We display in the console the difference (diff) between different versions of the specified file. Here, VERSION1 and VERSION2 are version identifiers, in accordance with the description given above, to the fossil finfo command . If they are not specified, then the difference between the latest version from the repository and the file in the working directory is displayed. If Tcl / Tk is installed (it is usually installed on Linux systems, but there is a port for Windows as well), you can use the -tk option - in this case, built-in graphical tools based on Tcl / Tk will be used to show the differences. If you have a GUI program for graphically presenting the difference between text files (I use examdiff.exe on Windows), you can pre-set it as the value of the Fossil diff-command parameterusing the web interface or the fossil settings diff-command command - then this program will be called when fossil diff is executed .

fossil gdiff
The same as fossil diff , only to display the differences, a program is used that is registered as the value of the Fossil gdiff-command parameter .

fossil tag add TAGNAME VERSION
fossil tag cancel TAGNAME VERSION
We add ( add ) or remove ( cancel ) the tag of the specified version of the repository. This label can be considered as an alias of the version identifier and used in the appropriate commands instead of the identifier, preferably with the tag: prefix. Typically, labels are placed on the most significant, staged versions of a project.

fossil revert
fossil revert source\wall\brick.c
fossil revert -r VERSION source\wall\brick.c
We return to the working directory the specified version of the file (or all files if the file name is not specified). If the version ( -r VERSION ) is not specified, then the last one is taken - the one that got into the repository during the last commit . The version identifier is specified in accordance with the rules described above (to the fossil finfo command ).

fossil undo
We cancel the changes in the working directory made by the revert , merge or update command (we will consider the last two later, in the second part).

Well and, of course, help - how could without it:
fossil help
fossil help add
Help without arguments displays a list of commands, and with the name of the command as an argument (for example, add , as in the example), a description of this command.

I can not help but tell about another team - fossil all . It performs the specified action with all open repositories:
fossil all list
fossil all changes
fossil all extras
fossil all pull
fossil all push
fossil all sync

list - displays a list of repositories, changes - a list of modified files in all repositories, etc.

Web interface, tickets, wiki
I already mentioned the Fossil web interface launched by the fossil ui command when I talked about configuring the repository. It looks something like this:

In addition to viewing and changing settings (Admin), here you can see the project history (Timeline), a list of files (Files) and each file separately, the structure of the project branches (Branches), tags (Tags), work with the Bug Tracking system (Tickets) and with Wiki - documentation.

Looking through the history (Timeline), you can select any version by clicking on its identifier (hash code in square brackets), and there you can see the list of files at that time, a list of changed files, differences from the previous version for each file (by clicking [ diff]), you can download the zip- or tar- archive of this version, edit its representation in the history, including tint, etc.

I would like to briefly dwell on the use of Tickets and Wiki. Tickets - in this case, this word will probably be correctly translated as “cards” - a way to implement the bug tracking system, Bug Tracking, although these cards, generally speaking, can be used not only for error messages, but also for planning work on the project . So, we select Tickets, then - New ticket and fill out the card - a brief summary, type, version number, to which this entry belongs, the degree of criticality, email and a detailed description in which you can use wiki markup, which means referring to any objects in the repository by their identifier - other cards, wiki pages, file versions. By the way, this possibility of using identifiers as links seems to me very valuable, since it increases the coherence of information in the repository, contributes to the maximum integration of all parts of the project. Once entered, Ticket appears in both the All tickets list and the Timeline. You can now open it, add additional comments, apply a resolution (fixed, rejected, Unable_To_Reproduce, Works_As_Designed, etc.). If ticket is closed, then atcommit of the corresponding correction, it is desirable to indicate the identifier of this card in square brackets, then in the version history in the corresponding line there will be a link to ticket.

Before you start using the Wiki, it is advisable to indicate the name of the project, if it has not already been done: Admin / Configuration - fill in the Project Name field and click the Apply Changes button. Select Wiki, click on the Castle project home page (we called the Castle project) and edit this page. We look at the rules of the used wiki markup in Formatting Rules. We use Preview Your Changes, to save click Apply These Changes. If everything is fine, then the created text should appear on the main page (Home) under the menu bar. Let me remind you that changes to wiki pages are captured by the version control system and appear in Timeline.
In addition to the usual named Fossil, it allows you to create time-related wiki pages, they are called events and appear in Timeline. You can create such an event by selecting Wiki and then Create a new event. We enter the time to which we attach the event, Timeline Comment - a line for Timeline, select a color and edit Page Content - i.e., in fact, the contents of the page. The Fossil documentation recommends using events as
• Milestones of the project - for example, major releases
• Developer blog entries describing the current status of the project, roadmaps for further development
• Project Milestones
• Project related news

Conclusion
So, in the first part of the review, the use of Fossil in single-user mode at one workstation was examined. We learned how to create a repository,
fossil new c:\fossil\castle.fossil
open, customize and replenish it,
c:
cd \projects\castle
fossil open c:\fossil\castle.fossil
fossil settings crnl-glob '*'
fossil settings encoding-glob '*'
fossil settings ignore-glob '*.o,*.obj,*.exe,*.bak,*.log'
fossil commit -m "Initial commit"