📜 ⬆️ ⬇️

Version Control Systems: Fossil Part II

We continue to talk about Fossil.

In the first part, we met with the use of Fossil in single-user mode in one workplace. The next step is to transfer the repository to another computer - from work to home, or to a laptop that we take with us on the trip. The easiest option is to just copy the repository, the benefit is just one file, to a new workplace. You can do this, but the simplest solution is not always the best, there is a chance that small problems will arise.

Single user mode on multiple workplaces.
The fact is that not only the version history is stored in the repository, but also some service information, in particular, the administrator name and password. The administrator's name is automatically generated when creating the repository, usually the username under which you are logged into the OS - and it may well be that this name on the computer where you copy the repository is different from the one with which the repository was created. In this case, commit will not work, and you will have to add the required user using fossil ui , or add the --user parameter to fossil commit each time. A cleaner way is to clone an existing repository with the fossil clone command. As in the first part of the article, we will proceed from the assumption that we have Windows, that all our repositories are stored in a separate directory c: \ fossil, that we are working on the Castle project, whose sources and on another computer we want to place in c: \ projects \ castle \ source \. In addition, suppose that we transfer the repository on a flash drive mounted as disk F. So, we clone:
')
fossil clone f:\castle.fossil c:\fossil\castle.fossil 

And open for future use:

 c: cd \projects\castle fossil open c:\fossil\castle.fossil 
At the same time, the files included in the repository will be unpacked into the current directory.

Before we go any further, we need to figure out the autosync parameter. If it is enabled (" on ", or 1), then when the fossil update command is executed, an attempt will be made to get the update first from the remote repository ( pull ), and when the fossil commit is executed, first pull and update , and immediately after the commit - push (send changes to the remote repository), and the address of the remote repository will be specified in the last executed command clone , push , pull , sync , remote-url . In our case, it will be f: \ castle.fossil, i.e., at every commit Fossil will first try to contact the file on the flash drive, and if it is not inserted, the commit will not be executed - this is hardly what we want to. Enabled autosync is good if our remote repository is located on a server on the local network, i.e. almost always available. In the case when the remote repository is actually a file on the flash drive, with which we transfer the changes we have been working from one place to another, this may not be very convenient. Therefore, before you start working with the repository, disable autosync :

 fossil settings autosync off 

Now you can continue working on the project in a new workplace, saving changes in the local repository as needed with the help of commit . To transfer changes to other workplaces, we use push (transferring changes from the local to the remote repository), pull (receiving changes from the remote to the local repository). You can use sync - this command makes pull and push . Thus, our workflow (workflow) is something like this:

Rewrote the update from the flash drive:
 fossil pull f:\castle.fossil fossil update 
The update command modifies the work files according to the contents of the local repository. At the same time, the changes that we made in the working files after the last commit (in fact, it’s not necessary to do so in single-user mode!), Fossil will try to merge.
Worked on the project, saved the changes ( commit ) to the local repository and sent them to the remote:
 fossil push f:\castle.fossil 
We come to another workplace - and again: pull , update , work ..., commit , push .

You can, in principle, instead of push, simply physically copy the repository file to a flash drive — in the case of such a single-user mode of operation, this is permissible, but using push is a “cleaner” option. What should definitely not be done is to physically copy the repository to the local place when this local is open - in this case, the local repository may be in conflict with the official repository that was created as a result of its discovery, which may lead to the loss of information about changes and, accordingly, to unpleasant slips.

It is more convenient, of course, not to carry the repository on a flash drive or other portable physical media, but to keep it on the server. You can use a third-party service like dropbox, or you can, if you can, place the repository on a server that you can administer. This is the option that we will look at further, especially since we will need it to organize multi-user work (you can also use the services of websites that provide hosting options for Fossil - repositories, for example, http://chiselapp.com/ or Sourceforge , but I’m I will not stop here on this).

Installing the repository on the server.
Actually, the installation is performed in the same way as we did from the flash drive - we rewrite our local repository on a flash drive or in an accessible place on the server and do fossil clone . The question is how to provide access to this newly created remote repository, which URL to use in Fossil commands.
There are three options for connecting to a remote repository:


The first option is, indeed, the easiest, to implement it you don’t need to do anything at all, except for how to clone the repository into the correct directory. Appeal to it is no different from the option with a flash drive, just use the path to the directory as it is mounted on your computer. But this method limits you to your local network. There is another drawback: since in this case we work not in client-server mode, but as with data on a file server, in the event of a failure (power off your computer, for example, or something with a connection) during recording to the remote repository file There may be problems.

To use an ssh connection, you must have an ssh server, respectively, and the fossil executable file must be copied to this server. In this case, the repository URL in the Fossil command will look like this:

 ssh://[userid[:password]@]host[:port]/path/repo.fossil 
If the absolute path is used, then one more slash must be placed before the path . If the fossil executable file is in a directory unknown to the system (i.e., inaccessible by SET PATH), should we add? Fossil = path_to_fossil / fossil to the URL.
Suppose that we have placed our castle.fossil repository on a Linux server in / usr / local / fossil, and the login on this server is alex. Then the push command, for example, might look like this (our server is 192.168.0.2):
 fossil push ssh://alex@192.168.0.2//usr/local/fossil/castle.fossil 
Once again, I note that in this case, the login to the server is used as the login name, and not the repository username.

Now about the third option - the use of http - server. The simplest thing is to execute the fossil server command on the server — as a result, the http server will be started there, the same as with the fossil ui command already familiar to us, the only difference is that now it can be accessed not only from the local, but also from any other computer on the network and now with web access we will have to log in to get full access to the repository. The URL in this case will look like this:
 http://[userid[:password]@]host[:port]/path 

Let me remind you that the default port is 8080, you can change it with the --port option of the fossil server command.
If the http-server supporting CGI is already raised on the server, you can use the Fossil executable file as a CGI-program (this is, according to the documentation, the official Fossil website works). To do this, in CGI - a directory on the server (usually this is cgi-bin), put this simple script here:

 #!/usr/bin/fossil repository: /usr/local/fossil/castle.fossil 

We assume here that the fossil executable is placed in / usr / bin. Do not forget, of course, to install the necessary rights to the files of the repository, the script and the corresponding directories. If we called the script file castle, the URL might look like this:

 http://[userid[:password]@]host/cgi-bin/castle 
here userid is the username of the repository. And the push command will look like this:

  fossil push http://alex@192.168.0.2/cgi-bin/castle 

If the http server does not support CGI, you can configure Fossil call via SCGI. You can enable the http service using inetd, xinetd, or stunnel. You can read more about this in the Fossil documentation , here I describe only what I tried with my own hands.
The option of using http, besides ease of use from any computer connected to the server via a local network or via the Internet, is also good because it provides a web service, we get, in fact, a web server of the project. Of course, the first thing that needs to be done is to set up access rights - in particular, for anonymous - all those who are not registered as users in the repository.

If we continue to use the repository exclusively, the workflow remains the same as when using the flash drive as a carrier for the remote repository (only the URL changes): pull , update , work ..., commit , push . Although, if we use a resource constantly connected to the same address as a remote repository, we can revise the relation to the autosync parameter and set it to " on ". In this case, the work cycle is shortened to update , the work ..., commit - pull and push will be executed automatically. Do not forget to check which address of the remote repository will be used (usually this is the last one used in the clone , pull , push or sync commands). This can be done with the fossil remote-url command. The same command can set the required URL by passing it as a parameter: fossil remote-url URL .

And one more important note concerning both single-user and multiplayer modes. Keep track of the correct time setting on computers! If you try to commit , when the current version in the local repository has a later date / time than the ones currently installed on the computer, the operation will not be performed and a corresponding message will be displayed. If you have the right time on your computer and still need to make this commit , do it with the --allow-older option. But it is better, of course, not to bring to this situation.

Multi-user mode.
The remote repository on the server is already installed. We create cloning from a remote local repository (which URL we used in the previous section), add this user to the remote one, register its rights, and - go ahead. Duty cycle is about the same as in single user mode, only now pull and update must be done before each commit (this is if autosync is disabled, if enabled - this is done automatically), since in the time elapsed from the previous pull the remote repository could be changed another user.

Here a new, previously unforeseen situation may arise. You updated your work files ( pull , update ) and started editing them. In the meantime, your colleague also edited something and sent it to the server ( commit , push ). You have completed your work and want to send changes to the server. Here are the following options:

1) Autosync is on or off, but you do a pull , update before commit , as it should be. Update will try to perform a merge, and if it passes normally, then ... everything is fine. If the merge cannot be made (for example, the changes were in the same line of the same file), then the update will display the corresponding message, you will have 3 new files for each "merged" with extensions ending in -baseline , -merge and -original, and in the "not poured" files new lines will appear in each disputed place, starting with "<<<<<<< BEGIN MERGE CONFLICT: ..." and ending with ">>>>>>> END MERGE CONFLICT ... ", there will be both the previous version (COMMON ANCESTOR content), and your version (local copy content), and the version of your colleague (MERGED IN content). You will have to make the necessary changes yourself by editing the file, and then make a commit .

2) Autosync is turned off and you forgot to pull , update before commit . Everything will pass without additional messages, without excesses, but as a result of commit a fork will be created in the repository - in fact, a new branch of the project. As stated in the documentation, Fossil fork is an unwanted, unintended branch . The bad thing is that neither you nor your colleague can even notice this, if you don’t look into the Timeline - there the split will immediately catch your eye. To fix this situation, you need to combine the resulting branches with the fossil merge command. If the merge fails, then, as in the previous case, it will have to be done independently and commit .
This second situation can arise not only as a result of forgetfulness, but also if you work offline for a while and are forced to save changes to the local commit repository, without synchronizing it with the server. In this case, keep in mind that you might be able to fork and check the Timeline after sending the changes to the server. And again: if Autosync is turned on for you, but for some reason you want to get fork instead of merging your changes with changes from other developers, you can run commit with the --allow-fork option.

Branches (branches).
I will not speak here about why the branching of the project is needed, why and in what cases it should be used, I’ll just tell you briefly how this is implemented in Fossil. Suppose we want to create a new branch ver_2_0:

  fossil branch new ver_2_0 trunk 
trunk is the branch from which we produce a branch, trunk is the name of the main trunk of any project. If we now execute the fossil branch list command, we will see that we now have 2 branches — trunk and ver_2_0, with the “*” flag marked as the branch — this means that it is the current branch. Creating a new branch does not change the status of the working files - we are still in the old trunk branch, you can check this with the fossil status command. To go to the new branch, perform

  fossil checkout ver_2_0 
or fossil co ver_2_0 , it’s the same thing. The checkout command replaces the working files with those that are in the local repository and sets the specified branch (if specified) as the current one. Now all our subsequent changes will be related to the ver_2_0 branch. If we need to make in the trunk branch the changes that we have developed in ver_2_0, go to the trunk and make the union:

 fossil co trunk fossil merge ver_2_0 

When merging, conflicts may arise - how I dealt with them above.

There are also so-called personal branches, they remain in the local repository and are not transferred to the server, such branches are formed if you add the --private parameter to the branch command .

Conclusion
Well, sort of, and everything that I planned to tell. Of course, not all the questions were covered here, not all the teams and not all the parameters (I think even a smaller part) of the teams that were discussed. But this is documentation. There is another interesting topic worth mentioning - this is the ability to create my own scripts on the built-in Tcl - like TH language, but I myself have not figured it out yet.

Finally, I would like to answer the question that was most often asked in the comments to the first part of the article: how Fossil is better than Git or Mercurial.
I am not trying to persuade anyone to switch to Fossil from another VCS, moreover, I consider it unproductive to change the VCS that you use to another one if everything suits you and there are no serious reasons for migration. The version control system is just a tool and it should not be in the forefront of your work. Another thing, if you only choose VCS for yourself - in this case it is worth considering Fossil as a completely worthy option that provides all the necessary features.
Is it better or worse? This is largely a matter of personal preference. I like the minimalism of Fossil. I like that to install the client, that the server just needs to copy one file, that there is no need to bring up a separate service for the server, that I can carry two small executable files (for Windows and for Linux) and several files — repositories — on the flash drive - and this enough to use it anywhere. I think its web interface is convenient and it seems important that it can be used locally. I like that the bug-tracking and wiki are built into the system, their data is stored in the same repository and tightly integrated with the rest of the repository content, that you can work offline with them, that you do not need to use the services of third-party web services and worry about your data in the closure of these services or changes in their policies. Surely there are people who will like it too.

Source: https://habr.com/ru/post/236489/


All Articles