[00:00.000 --> 00:12.200] Good evening, welcome to my talk. [00:12.200 --> 00:19.680] My talk today is on Tissue, a minimalist Git and plain text based issue tracker. [00:19.680 --> 00:22.360] Small projects need small tools. [00:22.360 --> 00:27.360] Many pre-software projects unfortunately use GitHub, a proprietary platform. [00:27.360 --> 00:34.360] When pre-software solutions such as GitLab and GitE do exist, they are not easy to host. [00:34.360 --> 00:40.440] They often require running complex database services and they tend to blindly imitate [00:40.440 --> 00:48.440] GitHub without thinking about ease of hosting for small independent programs. [00:48.440 --> 00:54.360] Now, GitHub is not popular for no reason. [00:54.360 --> 01:02.360] You come to the nice issue tracker. Issue trackers are really handy as a community when you are coordinating work. [01:02.360 --> 01:14.360] GitHub lets you host your project wiki, website, release star balls, etc. on their servers. [01:14.360 --> 01:17.360] Free hosting is always nice. [01:17.360 --> 01:25.360] It has a nice search interface to search through issues, commit messages and even code. [01:25.360 --> 01:39.360] It allows you to easily hand over your projects to new maintenance when you grow tired of your own code or you no longer have the time to maintain them. [01:40.360 --> 01:48.360] Tissue tries to do all this but in its own way and still be minimal and easy to host and maintain. [01:48.360 --> 01:54.360] It requires no database servers whatsoever, not even SQLite. [01:54.360 --> 01:59.360] Issues are simply plain text files committed into your Git repo. [01:59.360 --> 02:05.360] Tissue comes with a powerful full-text search engine built on this APN search engine library. [02:05.360 --> 02:12.360] And as an added bonus, you can even search through your documentation and commit messages. [02:12.360 --> 02:26.360] Now, since the entire state of a Tissue repository is in Git, it is really easy to move from one server to another or to backup and restore. [02:26.360 --> 02:31.360] To backup, you merely have to backup the Git repo, which you have to do anyway. [02:31.360 --> 02:42.360] Backup is a really important thing and something that should be very painless for self-hosted services. [02:42.360 --> 02:50.360] I remember many years ago when I was using GNU Social and quite active on the FedEverse. [02:50.360 --> 02:59.360] I would notice that from time to time instances would vanish from the Internet. [02:59.360 --> 03:15.360] It turns out that this is because people were not backing up their GNU Social instances correctly and they would lose it all and not be able to put it back when a hard disk crashed. [03:15.360 --> 03:30.360] Now, in theory, it is perfectly possible to backup GNU Social instances and restore it when necessary. [03:30.360 --> 03:33.360] But in practice, it does not always happen. [03:34.360 --> 03:55.360] This is because people running self-hosted instances are usually doing it in their free time and do not necessarily have the mental bandwidth to figure out all the details and implement all the best practices. [03:55.360 --> 04:06.360] So, any piece of software that is aiming for wide adoption among self-hosted services should be really simple to use. [04:06.360 --> 04:13.360] It cannot merely be free software. That alone is not enough. Simplicity and minimalism are absolutely necessary. [04:13.360 --> 04:27.360] Let me show you how tissue is used in practice. [04:27.360 --> 04:33.360] Here is the tissue repository. You see the tissue code here. [04:33.360 --> 04:38.360] It goes into the issues directory. You see many issue files here. [04:38.360 --> 04:43.360] Each file here corresponds to one issue. [04:43.360 --> 04:54.360] This is a typical issue file. It is written in gemtext format. [04:54.360 --> 04:59.360] Gemtext is a markdown-like format used in the Gemini protocol. [05:00.360 --> 05:08.360] It is really minimal and interesting. You should definitely check out gemini and gemtext if you haven't already. [05:08.360 --> 05:16.360] This issue has its title, tag and text. [05:16.360 --> 05:19.360] Finally, this particular issue is closed already. [05:19.360 --> 05:21.360] So, you see closed here. [05:24.360 --> 05:27.360] Let's try another one. [05:27.360 --> 05:30.360] This is another issue. It is similar again. [05:30.360 --> 05:34.360] We have a title, tags and text. [05:37.360 --> 05:43.360] Now, let's actually try to use tissue on the command line. [05:43.360 --> 05:46.360] Let me run tissue. [05:48.360 --> 05:51.360] This lists all issues. [05:51.360 --> 05:58.360] The commit message is that tissue knows a lot. [05:58.360 --> 06:03.360] Maybe we can search through and list only the closed issues. [06:03.360 --> 06:07.360] Tissue search is closed. [06:07.360 --> 06:10.360] There are three closed issues here. [06:10.360 --> 06:18.360] Maybe we only want to look at issues that have the word emacs interface in it. [06:18.360 --> 06:21.360] Here you have those. [06:27.360 --> 06:32.360] Tissue is a small project with only a few issues and commit messages. [06:32.360 --> 06:41.360] Perhaps it would be more interesting to look at a larger project like geeks. [06:41.360 --> 06:46.360] Geeks doesn't actually use tissue. [06:47.360 --> 06:51.360] But if it did, what would the search experience be like? [06:51.360 --> 07:01.360] Here I have a locally running instance of tissue web interface which has indexed all of geeks' commit messages, [07:01.360 --> 07:06.360] all of its manual and all of the geeks' cookbook as well. [07:06.360 --> 07:11.360] Now, let's try to search it. [07:11.360 --> 07:15.360] Perhaps I want to know something about the geeks garbage collector. [07:15.360 --> 07:18.360] I run geeksgc. [07:21.360 --> 07:26.360] Let's look at only the documentation for now. [07:26.360 --> 07:30.360] The first result is the invoking geeksgc page. [07:30.360 --> 07:37.360] I can click on it and immediately jump to the relevant section of the geeks manual. [07:38.360 --> 07:51.360] Now, interestingly there are many of these invoking pages that I keep having to refer to once in a while. [07:51.360 --> 07:59.360] But it's really hard to navigate the manual hierarchy and get to the page reliably. [07:59.360 --> 08:10.360] It would be really handy to have a search interface like this where you can simply jump to the section instead of having to traverse through the manual. [08:10.360 --> 08:15.360] Let's search for WireGuard. [08:15.360 --> 08:24.360] Here again you have a geeks cookbook page that tells you how to set up a WireGuard VPN. [08:24.360 --> 08:26.360] That's nice. [08:26.360 --> 08:34.360] But it's not just documentation, we could also look for commit messages that mention the word WireGuard. [08:34.360 --> 08:40.360] Let's look at the search for useg expressions. [08:40.360 --> 08:45.360] Now, many geeks packages are being rewritten to useg expressions. [08:45.360 --> 08:51.360] So, you'll find a lot of commit messages that mention useg expressions. [08:51.360 --> 08:59.360] One important thing to note here is that even commit messages with usingg expressions is matched. [08:59.360 --> 09:07.360] They have been understanding the English language enough to know that using is just a derived form of use. [09:07.360 --> 09:12.360] So, what you see here is it's not a simple grep-like search. [09:12.360 --> 09:16.360] It is a more powerful, more natural search. [09:16.360 --> 09:21.360] In fact, searching commit messages with grep is a real pain. [09:21.360 --> 09:29.360] It should be using something with real natural language search like this. [09:29.360 --> 09:36.360] Now, let's look at, maybe we want to look at all commits that update the SQLite package. [09:36.360 --> 09:39.360] So, we search for update SQLite. [09:39.360 --> 09:43.360] Here you see, all of these are SQLite updating commits. [09:43.360 --> 09:46.360] That's nice. [09:46.360 --> 10:00.360] Maybe we want to look at commits that update SQLite and remove a patch. [10:00.360 --> 10:01.360] See that again here. [10:01.360 --> 10:06.360] There is an update commit with the patch being removed. [10:06.360 --> 10:13.360] Once again, it's important to note that the terms in the search query are scattered throughout the commit message. [10:13.360 --> 10:24.360] They are not exact search matches like you would get with grep. [10:24.360 --> 10:25.360] That's it for the demo. [10:25.360 --> 10:31.360] I hope that gave you some flavor for what tissue feels like. [10:31.360 --> 10:33.360] That's it for my talk as well. [10:33.360 --> 10:38.360] I'm an Israeli tank peoter and the G-Network team. [10:38.360 --> 10:49.360] Tissue began as peotter's idea and grew very iteratively and organically within the G-Network team as an internal issue tracker. [10:49.360 --> 11:00.360] Tissue certainly wouldn't be what it is today without all the early experimentation that they kindly participated in. [11:00.360 --> 11:02.360] Thank you for listening. [11:02.360 --> 11:10.360] Unfortunately, I couldn't make it to Brussels this year due to visa delays. [11:10.360 --> 11:16.360] Who would have thought that crossing an imaginary line on a map would be so difficult? [11:16.360 --> 11:20.360] But maybe next year. [11:20.360 --> 11:22.360] Have a nice day. [11:32.360 --> 11:34.360] Thank you.