{"id":1000,"date":"2019-12-05T12:57:19","date_gmt":"2019-12-05T00:57:19","guid":{"rendered":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/?p=1000"},"modified":"2019-12-05T12:57:19","modified_gmt":"2019-12-05T00:57:19","slug":"an-alternative-to-git-fossil-a-quick-review","status":"publish","type":"post","link":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/?p=1000","title":{"rendered":"An alternative to git, fossil a quick review"},"content":{"rendered":"<p>First a disclaimer, after reviewing <em>fossil<\/em> I will be remaining with <em>git<\/em> 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 &#8216;offsite backup&#8217; for source code that makes it not suitable for me.<\/p>\n<p>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 <em>fossil<\/em> repositories. <em>One advantage over <\/em><em>git<\/em> 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).<\/p>\n<p>It should also be noted that <em>fossil<\/em> runs on multiple platforms wheras <em>git<\/em> 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.<\/p>\n<p>For migration it is possible to convert project repositories between <em>fossil<\/em> and <em>git<\/em> formats with simple export\/import commands, I have an example of moving a <em>git<\/em> application to <em>fossil<\/em> later in the post.<\/p>\n<p>The <em>fossil<\/em> application and documentation is available at <a href=\"https:\/\/fossil-scm.org\/fossil\/doc\/trunk\/www\/index.wiki\">https:\/\/fossil-scm.org\/fossil\/doc\/trunk\/www\/index.wiki<\/a>.<\/p>\n<p>It should be noted that <em>fossil<\/em> provides many additional features over <em>git<\/em> on a per-project basis such as a WIKI and problem ticketing system for each individual <em>fossil<\/em> 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 <em>fossil<\/em> to <em>git<\/em> although if you chose to stick with <em>fossil<\/em> it is obviously useful.<\/p>\n<p>It should also be noted that I have been completely unable to get the &#8216;fossil push&#8217; operation to work.<\/p>\n<p>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&#8217;s requirement that users be specifically added for update access may make it a perfectly useful problem management system.<\/p>\n<h2>The major differences between git and fossil<\/h2>\n<p>A major difference between <em>git<\/em> and <em>fossil<\/em> is that <em>git<\/em> uses the Linux host filesystem for file archiving and versioning, <em>fossil<\/em> uses SQLite databases for each project, as <em>fossil<\/em> 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&#8217;ing the one SQLite database file containing the project I see no real benefit over a simple &#8216;git export&#8217;, scp and &#8216;git import&#8217; to move a git project.<\/p>\n<p>Another major difference between <em>git<\/em> and <em>fossil<\/em> is that <em>git<\/em> is pretty much open on who can make changes available encouraging contributers, <em>fossil<\/em> works in reverse permitting only trusted users to make changes so for each project you must create\/authourise users.<\/p>\n<p>Fossil also provides on a per-project basis a WIKI, Ticketing system, user forum and tech-note features al contained witrhin the same <em>fossil<\/em> binary that provides the command line interface to the repositories.<\/p>\n<h2>The basic source versioning funtions<\/h2>\n<p>There will be a learning curve in switching from <em>git<\/em> to <em>fossil<\/em> as while the<br \/>\ncommands are similar they are not identical, so <em>git<\/em> users will be extremely frustrated in switching to <em>fossil<\/em> as commands &#8216;almost work&#8217; but need tweaking.<\/p>\n<p>Also frustrating is that <em>fossil<\/em> 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.<\/p>\n<pre>\r\nAutosync:  http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nPull done, sent: 439  received: 824  ip: 127.0.0.1\r\nempty check-in comment.  continue (y\/N)? y\r\nNew_Version: f691c302f1b2b0dedfd4cd60bd91a965dc83ce84aaea86e705b24adcb7887cd9\r\nAutosync:  http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils\r\nRound-trips: 1   Artifacts sent: 2  received: 0\r\nSync done, sent: 1142  received: 859  ip: 127.0.0.1\r\nWarning: The check-in was successful and is saved locally but you\r\n         are not authorized to push the changes back to the server\r\n         at http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils\r\n<\/pre>\n<p>The issue with remote authentication to the <em>fossil<\/em> remote repository is mentioned quite often in this post so read on.<\/p>\n<p>Both <em>git<\/em> and <em>fossil<\/em> 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.<\/p>\n<h2>Remote repositories<\/h2>\n<p>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.<\/p>\n<p>Unlike the complexity of <em>git<\/em> it is simple to create a remote repository using <em>fossil<\/em> as if you have a webserver running already it can be easily configured to run the <em>fossil<\/em> binary as a CGI interface to provide access to one or multiple repositories. The <em>fossil<\/em> binary can also run as a server to provide remote access to a single repository.<\/p>\n<p>Note: for local use you can also use the &#8216;fossil ui&#8217; 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. <\/p>\n<p>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.<\/p>\n<p>The main difference between running <em>fossil<\/em> 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 <em>fossil<\/em> 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.<\/p>\n<pre>\r\nfossil clone http:\/\/localhost\/cgi-bin\/fossil.sh mvs38j_utils.fossil\r\nfossil clone http:\/\/localhost\/cgi-bin\/fossil.sh\/<em>mvs38j_utils<\/em> mvs38j_utils.fossil\r\n<\/pre>\n<h3>Clone a repository<\/h3>\n<p>One thing is important to note when cloning a repository, the project id and <b>admin user password is changed<\/b> for the local copy.<\/p>\n<pre>\r\n[mark@vosprey3 temp]$ \/home\/fossil\/fossil clone http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils mvs38j_utils.fossil\r\nRound-trips: 2   Artifacts sent: 0  received: 181\r\nClone done, sent: 548  received: 652209  ip: 127.0.0.1\r\nRebuilding repository meta-data...\r\n  100.0% complete...\r\nExtra delta compression... \r\nVacuuming the database... \r\nproject-id: f51c618d56d51898d27f0f46225829bf32931c73\r\nserver-id:  6472f0d2048663b39577dddb4ddc8c70c35a3852\r\nadmin-user: mark (password is \"fAXrZB4vdP\")\r\n<\/pre>\n<p>Another thing to note is that the change seems to serve no purpose other than to obscure the actual password used on the <em>fossil<\/em> remote repository, no password is not needed to open, branch or coomit to the local copy. <\/p>\n<p>What is cloned is the SQLite database itself rather than a filesystem tree <em>git<\/em> users are used to. A &#8216;fossil open&#8217; or &#8216;fossil branch&#8217; of the local copy from a different work directory is needed to access the files within the repository.<\/p>\n<pre>\r\n[mark@vosprey3 temp]$ ls\r\nmvs38j_utils.fossil\r\n<\/pre>\n<h3>Pull from the remote repository<\/h3>\n<p><b>You cannot &#8216;pull&#8217; a remote repository unless you have cloned it to a local copy first<\/b>. Or createing an new empty project to pull into may work but I have not tried that, either way an extra step.<\/p>\n<pre>\r\n[mark@vosprey3 temp]$ \/home\/fossil\/fossil pull http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils -R mvs38j_utils.fossil\r\nrepository does not exist or is in an unreadable directory: mvs38j_utils.fossil\r\n<\/pre>\n<p>After a clone it is fine.<\/p>\n<pre>\r\n[mark@vosprey3 temp]$ \/home\/fossil\/fossil clone http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils mvs38j_utils.fossil\r\nRound-trips: 2   Artifacts sent: 0  received: 181\r\nClone done, sent: 548  received: 652209  ip: 127.0.0.1\r\nRebuilding repository meta-data...\r\n  100.0% complete...\r\nExtra delta compression... \r\nVacuuming the database... \r\nproject-id: f51c618d56d51898d27f0f46225829bf32931c73\r\nserver-id:  e1f90ed7c925f8da14a0a8ce997dbe28eb46138b\r\nadmin-user: mark (password is \"r4Fg2wbiTW\")\r\n\r\n[mark@vosprey3 temp]$ \/home\/fossil\/fossil pull http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils -R mvs38j_utils.fossil\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nPull done, sent: 322  received: 824  ip: 127.0.0.1\r\n[mark@vosprey3 temp]$ \r\n<\/pre>\n<h3>Push to the remote repository<\/h3>\n<p><b>Does not appear to be possible to push to the source repository<\/b>.<\/p>\n<p>In the repository configuration on the remote server &#8216;Allow HTTP_AUTHENTICATION authentication&#8217; 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.<\/p>\n<p>Also in the user configuration on the remote server side my userid was given access to every privalege (every checkbox was checked).<\/p>\n<pre>\r\n[mark@vosprey3 temp]$ \/home\/fossil\/fossil push http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils -R mvs38j_utils.fossil\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nError: not authorized to write\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nPush done, sent: 780  received: 391  ip: 127.0.0.1\r\n\r\n[mark@vosprey3 temp]$ \/home\/fossil\/fossil push http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils -R mvs38j_utils.fossil -B mark:LhikpKwBeP\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nError: not authorized to write\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nPush done, sent: 824  received: 391  ip: 127.0.0.1\r\n\r\n[mark@vosprey3 temp]$ \/home\/fossil\/fossil push http:\/\/localhost\/cgi-bin\/fossil.sh\/mvs38j_utils -R mvs38j_utils.fossil -B mark:r4Fg2wbiTW\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nError: not authorized to write\r\nRound-trips: 1   Artifacts sent: 0  received: 0\r\nPush done, sent: 824  received: 391  ip: 127.0.0.1\r\n[mark@vosprey3 temp]$\r\n<\/pre>\n<p><b>Obviously this is a show stopper<\/b>. Just as obviously there must be a way to do it but the documentation is not clear.<\/p>\n<h2>Migrating a <em>git<\/em> project to a <em>fossil<\/em> project<\/h2>\n<p>That is covered quite well at <a href=\"https:\/\/fossil-scm.org\/home\/doc\/trunk\/www\/inout.wiki\">https:\/\/fossil-scm.org\/home\/doc\/trunk\/www\/inout.wiki<\/a>.<\/p>\n<p><quote><br \/>\nFossil 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.<br \/>\n<\/quote><\/p>\n<p>Below is how simple it is, I exported one <em>git<\/em> project, scp&#8217;ed the output to a machine with fossil on it, and imported it. It is that simple to move a <em>git<\/em> project to a <em>fossil<\/em> project. Not only managed source is imported but also a full checkin\/change-history.<\/p>\n<pre>\r\n[mark@phoenix mvs38j_utils]$ git fast-export --all > \/home\/mark\/mvs38j_utils.git.data\r\n[mark@phoenix mvs38j_utils]$ scp \/home\/mark\/mvs38j_utils.git.data mark@vosprey3:\/home\/mark\r\n[mark@vosprey3 fossil]$ cat ~\/mvs38j_utils.git.data | .\/fossil import --git mvs38j_utils.fossil\r\nRebuilding repository meta-data...\r\n  100.0% complete...\r\nVacuuming... ok\r\nproject-id: f51c618d56d51898d27f0f46225829bf32931c73\r\nserver-id:  24bc9ec6173188540a5598e64c2ce0d548177456\r\nadmin-user: mark (password is \"LhikpKwBeP\")\r\n[mark@vosprey3 fossil]$ \r\n<\/pre>\n<p>The admin-user\/password combination can be used to login to the <em>fossil<\/em> web interface whether by <em>fossil ui<\/em> if you are on a desktop of via the CGI scripts if you have <em>fossil<\/em> 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.<\/p>\n<h2>Integrating <em>fossil<\/em> into an existing WebServer<\/h2>\n<p>I created a new directory specifically for <em>fossil<\/em> 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. <b>I also placed the fossil binary in that directory<\/b>.<\/p>\n<p>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 <em>git<\/em> as discussed earlier.<\/p>\n<pre>\r\nmkdir \/home\/fossil\r\nchmod 777 \/home\/fossil\r\ntouch \/home\/fossil\/fossil_errors.log\r\nchmod 666 \/home\/fossil\/fossil_errors.log\r\ncat << EOF > \/var\/www\/cgi-bin\/fossil.sh\r\n#!\/home\/fossil\/fossil\r\ndirectory: \/home\/fossil\r\n#repository: \/home\/fossil\/mvs38j_utils.fossil\r\nerrorlog: \/home\/fossil\/fossil_errors.log\r\nnotfound: http:\/\/mdickinson.dyndns.org\/error_pages\/no_fossil_repo.html\r\nrepolist\r\ntimeout: 120\r\nsetenv: SQLITE_TMPDIR=\/var\/tmp\r\nsetenv: TEMP=\/var\/tmp\r\nsetenv: FOSSIL_HOME=\/home\/fossil\r\nEOF\r\nchmod 755 \/var\/www\/cgi-bin\/fossil.sh\r\n<\/pre>\n<p>Key vaules to note are &#8216;repository&#8217; plus the &#8216;directory&#8217; and &#8216;repolist&#8217; combination.<\/p>\n<p>If &#8216;repository&#8217; 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.<\/p>\n<p>However if &#8216;directory&#8217; is used you may place many xxx.fossil databases in the directory and access them by name <em>if you know the name<\/em> 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 &#8216;repolist&#8217; value is also set then browsing to the URL above gives you a list of available databases you can use to select from.<br \/>\n 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.<\/p>\n<h2>Additional features <em>fossil<\/em> provides via it&#8217;s web interface<\/h2>\n<p>To be useful <em>fossil<\/em> 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 &#8216;fossul ui&#8217; command that is for single user use; and as I am testing fossil on a headless server (no gui) I cannot test that.<\/p>\n<p>Via the web interface that comes bundled with the <em>fossil<\/em> binary you also have access to a project specific WIKI, Ticketing system, user Forum and tech notes. It also provides nicely formatted &#8216;timelines&#8217; of changes made throughout the application life.<\/p>\n<p>All those features are specific to the project you are working with and part of the SQLite database for the project.<\/p>\n<ul>\n<li>If you are working on more than one project it would therefore make sense to use at a minimum a sperate Ticketing system<\/li>\n<li>or if you are a small shop you could use a <em>fossil<\/em> project as nothing but a Ticketing system as the WIKI, Tech notes, and Forum would provide additional benefits for that<\/li>\n<\/ul>\n<h2>Summary<\/h2>\n<p><em>fossil<\/em> can replace all the <em>git<\/em> 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.<\/p>\n<p>If you already use github or gitlab your choices are to convert the projects to <em>fossil<\/em> databases and move everything in-house, or continue to use <em>git<\/em>. I personally push to github from multiple sources so <em>fossil<\/em> is of no use to me as github must be the authoritive source rather than a local <em>fossil<\/em> repository in my environment.<\/p>\n<p>Also as noted many times in this post I was unable to get the &#8216;push&#8217; 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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <a href=\"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/?p=1000\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-1000","post","type-post","status-publish","format-standard","hentry","category-my-nux-thoughts-and-notes"],"_links":{"self":[{"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1000","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1000"}],"version-history":[{"count":5,"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1000\/revisions"}],"predecessor-version":[{"id":1005,"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1000\/revisions\/1005"}],"wp:attachment":[{"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1000"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1000"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mdickinson.dyndns.org\/php\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}