1. 28
  1. 8

    As a satisfied git user, this seems fair. The tldr is: fossil uses substantially the same data structure as git but makes completely opposite choices because it’s optimized for smaller development teams.

    I’d love to hear from someone who has used both extensively and prefers fossil. What’s it like? What’s lost that git users rely on? What huge wins does fossil open up?

    1. 8

      I actually go so far as to just use Fossil for most of my websites. The wiki in markdown mode works great for my sites.

      What’s lost that git users rely on?

      The big thing is, git allows mutability, in fact all of git is basically a big fungible ball of mud. Fossil is much more immutable. If you think your VCS should allow mutable history, Git is for you. If you think your commits are immutable history, you should take a serious look at Fossil. I’m not sure there is a “right” answer here, it just depends on your perspective. Personally I’m an immutable person, that does mean you get the occasional commit message that looks like: ‘oops, fix typo’. But you can be fairly confident Fossil’s history is what actually happened and not a cleaned up version of reality.

      1. 11

        For what it’s worth, the commit graph in git is immutable. The only thing mutable are the references. What’s different is that in git you can move the references however you please, with no restrictions to move them along the edges of the commit graph.

        In fossil, you can only converge the timelines. In git, you can jump between them.

        1. 7

          A big realization for me was that the git graph itself is versioned in the reflog. Using git reflog to restore old references is hugely valuable and I’m way more confident using git because of it. But to be fair, those commits are only stored on my local machine, will eventually be gc-ed and won’t be pushed to a remote. Fossil would track them everywhere.

        2. 6

          Could you elaborate a bit on the value of immutability to you? I fall into the mutability camp because I find the additional context is rarely worth the value when it costs so much to untangle. I’d rather use the mutability to create untangled context and have that be the only artifact that remains. I’m not disagreeing that the immutability has value to you, I’m just seeking understanding since I experience things differently.

          1. 5

            I generally have two diametrically opposed views on immutability:

            • In other people’s repos, I want immutability with no exceptions. If I clone your repo, nothing you do should be able to modify the history that I think I have, so I can always find a common ancestor between your version and my fork and merge back or pull in new changes.
            • In my own repo, I want the flexibility to change whatever I want, commit WIP things, move fixes back to the commit that introduced the bug, and so on.

            I think GitHub’s branch protection rules are a good way of reconciling this. The main branch enforces immutable history, as do release branches. Ideally tags would also be immutable. Anything else is the wild west: if you work from those branches then don’t expect them to still exist upstream next time you pull and you may need to resolve conflicts later. I’d like a UI that made this distinction a lot more visible.

            1. 2

              This is definitely a reasonable perspective.

              Question, what is the point of committing WIP stuff?

              1. 3

                Locally, so that I have an undo button that works across files, so once something is working and I want to clean it up, I can always see what I’ve changed and broken during cleanup.

                Publicly, so that I can get feedback (from humans or CI), incorporate it, and then clean up the result so that, when it’s merged, everything in the history is expected to be working. This means that other people can bisect to find things that broke and not have to work out if a particular version is expectedly or unexpectedly broken. It also means that people merging don’t see conflicts in places where I made a change in a file, discovered I didn’t need it, reverted it, and they did a real change in that location.

                1. 1

                  Thanks!

                  For me and us @ $WORK, the undo button is either ZFS snapshots(exposed as ~/.snapshots) or $EDITOR’s undo functionality.

                  For human feedback, we have a shared user machine we work from or we use other more general purpose tools, like desktop screen sharing(typically tmux, or guacamole).

                  For CI feedback, since our CI/CD jobs are just nomad batch jobs, it’s just a nomad run project-dev.nomad command away.

                  I.e. we prefer general tools we have to use anyway to solve these problems, instead of specific tools.

                  1. 3

                    For me and us @ $WORK, the undo button is either ZFS snapshots(exposed as ~/.snapshots) or $EDITOR’s undo functionality.

                    That requires me to either:

                    • Have a per-source-tree ZFS dataset (possible with delegated administration, but a change from just having one for my home directory and one for my builds which doesn’t get backed up and has sync turned off)
                    • Tracking metadata externally about which of my snapshots corresponds to a checkpoint of which repo.

                    In contrast, git already does this via a mechanism that is the same one that I use for other things. Vim has persistent undo, which is great for individual files, but when a change spans a dozen files then trying to use vim’s undo to go back to (and compare against) the state from the middle of yesterday afternoon that worked is hard.

                    For human feedback, we have a shared user machine we work from or we use other more general purpose tools, like desktop screen sharing(typically tmux, or guacamole).

                    That requires everyone that you collaborate with to be in the same company as you (or introduces some exciting security problems for your admin team to have to care about), for your code review to be synchronous. The first is not true for me, the second would be problematic given that I work with people distributed across many time zones. Again, GitHub’s code review doesn’t have those problems.

                    For CI feedback, since our CI/CD jobs are just nomad batch jobs, it’s just a nomad run project-dev.nomad command away.

                    That’s fine if everyone running your CI has deploy permissions on all of the infrastructure where you do testing.

                    I.e. we prefer general tools we have to use anyway to solve these problems, instead of specific tools.

                    The tools that you use have a lot of constraints that would prevent me from using them in most of the places where I use git.

                    1. 1

                      Around CI/CD. For local testing with nomad it can be as simple as download the nomad binary then nomad agent -dev then nomad run <blah.nomad> and you can be off to the races, running CI locally.

                      We don’t do that, because @ $WORK, our developers are all in-house and it’s a non-issue, to share resources.

                      Just to be clear, I’m not trying to convert you, just for those following along at home.

                      Also, within Fossil’s commits, you can totally hide stuff from the timeline, similar to git rebase, using amend

                      1. 1

                        Thanks for the exchange! It’s interesting seeing the different trade-offs on workflow.

                        For those following along, another way, totally within fossil to do undo across large amounts of code change is just generate a sqlite patch file instead of a commit. it’s easy enough: fossil patch create <blah.patch> and to undo: fossil patch apply <blah.patch> The patch file will include by default all uncommitted changes in the repo.

                    2. 1

                      an undo button that works across files, so once something is working and I want to clean it up, I can always see what I’ve changed and broken during cleanup.

                      The staging area is underappreciated for this problem. Often when I hit a minor milestone (the tests pass!) I’ll toss everything into staged and then try to make it pretty in unstaged. With a good git UI it’s easy to look at the unstaged hunks in isolation and blow them away if I mess up. Good code gets promoted to the staging area and eventually I get a clean commit.

                      …and then I end up with lots of messy commits anyway to accommodate the “humans or CI” cases. :)

                    3. 1

                      In short, for backing it up or for pushing out multiple commits to create a design sketch.

                      1. 1

                        The Fossil “Rebase Considered Harmful” document provides a lot of reasons for committing WIP: bisect works better, cherry-picks work better, backouts work better. Read the doc for more: https://www2.fossil-scm.org/home/doc/trunk/www/rebaseharm.md

                        Rebase is a hack to work around a weakness in git that doesn’t exist in fossil.

                        The Git documentation acknowledges this fact (in so many words) and justifies it by saying “rebasing makes for a cleaner history.” I read that sentence as a tacit admission that the Git history display capabilities are weak and need active assistance from the user to keep things manageable. Surely a better approach is to record the complete ancestry of every check-in but then fix the tool to show a “clean” history in those instances where a simplified display is desirable and edifying, but retain the option to show the real, complete, messy history for cases where detail and accuracy are more important.

                        So, another way of thinking about rebase is that it is a kind of merge that intentionally forgets some details in order to not overwhelm the weak history display mechanisms available in Git. Wouldn’t it be better, less error-prone, and easier on users to enhance the history display mechanisms in Git so that rebasing for a clean, linear history became unnecessary?

                    4. 5

                      Sometimes it’s policy/law. When software starts mucking about with physical things that can kill/maim/demolish lives, stuff has to be kept track of. Think airplane fly by wire systems, etc. Fossil is good for these sorts of things, git could be with lots of policy around using it. Some industries would never allow a git rebase, for any reason.

                      • The perspective of Fossil is: Think before you commit. It’s called a commit for a reason.
                      • The perspective of Git is, commit every nanosecond and maybe fix the history later.

                      Of course history being immutable can be annoying sometimes, but history is messy in every version of history you look at, except perhaps kindergarten level history books :P I’m not a kindergartener anymore, I can handle the real history.

                      For me at $WORK, it’s policy.

                      1. 6

                        Ah, a policy reason certainly makes sense. I work in FinTech, where policy and/or law has not quite caught up to software to burden us with a more deeply ingrained moral responsibility to assure accountability of the software we write.

                        • The perspective of Fossil is: Think before you commit. It’s called a commit for a reason.
                        • The perspective of Git is, commit every nanosecond and maybe fix the history later.

                        Of course history being immutable can be annoying sometimes, but history is messy in every version of history you look at, except perhaps kindergarten level history books :P I’m not a kindergartener anymore, I can handle the real history.

                        This is condescending. Human beings make mistakes and storing those mistakes in all cases isn’t always a valuable artifact. Imagine a text editor that disallows text deletions. “You should have thought harder before typing it.” Come on, dude.

                        1. 7

                          Imagine a text editor that disallows text deletions.

                          We call that Blockchain Notepad.

                          1. 4

                            Thanks, I hate it!

                          2. 3

                            I had a :P in there :)

                            I apologize, but come on, it’s not like your comparison is remotely fair either :)

                            Human beings make mistakes and storing those mistakes in all cases isn’t always a valuable artifact.

                            I agree. Fossil(and git) both have ways to fix mistakes that are worth cleaning up. Git just has more of them. See “2.7 What you should have done vs. What you actually did” in the OP’s link.

                            1. 1

                              One thing I’m seeing about fossil that illuminates things a bit is that it looks like it might be possible to limit what sets of changes you see as a product of querying the change sets. This seems useful - not to reproduce something git-like - but to limit only to the changes that are considered more valuable and final than anything more transient. If that’s the case, I can see the “mess” of fossil being less of a problem, though with the added cost of now needing to be comfortable with querying the changes.

                          3. 5

                            I’d much rather have cleaned up history than try to bisect around half-finished commits.

                            1. 3

                              From a Fossil perspective, half finished commits belong locally or in .patch files to move around(which in Fossil land are sqlite3 files, not diffs). They don’t belong in commits.

                              To be clear I agree with you, bisecting half-finished commits are terrible. Fossil just has a different perspective and workflow than Git when it comes to this stuff.

                              1. 2

                                I imagine that the way this would get handled in fossil land is people making local half commits then redrafting the changes cleanly on another branch and using that as the official commits to release

                              2. 3

                                There’s a series of steps that any change takes as it passes through decreasingly mutable tiers of storage, so to speak:

                                • typing moves things from the programmer’s brain to an editor buffer
                                • saving moves things from an editor buffer to a file
                                • committing moves things from a file to a (local) repo’s history
                                • pushing moves things from a local repo to a (possibly) public one

                                The question is at what level a given change becomes “permanent”. With git it’s really only when you’ve published your history, whereas it sounds like fossil’s approach doesn’t really allow the distinction between the last two and hence that happens on every (local) commit.

                                You could move the point-of-no-undo even earlier and install editor hooks to auto-commit on every save, or save and commit on every keystroke, but I think most people would agree that that would produce an unintelligible useless mess of history, even if it is “a more accurate record of reality” – so even in the fossil approach you’re still looking at a somewhat massaged, curated view of the development history. I think git’s model just makes that curation easier, by allowing you to create “draft” commits and modify them later.

                                1. 2

                                  Fossil’s perspective would be, once it’s committed it is immutable, but you can do reporting on it and make it spit out whatever you want. i.e. Fossil really is just a fancy UI and some tooling around a SQLite database. There is basically no end to what one can do when your entire code tree is living in a SQL database.

                                  i.e. You don’t change the history, you change the report of history to show the version of reality that is interesting to you today.

                                  Fossil even includes an API for it: https://www2.fossil-scm.org/home/doc/trunk/www/json-api/api-query.md Not to mention the built-in querying available for instance in the timeline view

                                2. 3

                                  While I disagree with conclusion, I appreciate you taking the time to explain this way of looking at it. The legality angle seems reasonable, (and, ofc, if you have no choice, you have no choice) but digging further I have some questions for you….

                                  1. By this line of reasoning, why is the fossil commit the unit of “real history”? Why not every keystroke? I am not just being facetious. Indeed, why not screen record every editing session?
                                  2. Given that the fossil commit has been deemed the unit of history, doesn’t this just encourage everyone to big-batch their commits? Indeed, perhaps even use some other mechanism to save ephemeral work while I spend hours, or even days, waiting for my “official work” to be done so that I can create clean history?

                                  I’m not a kindergartener anymore, I can handle the real history.

                                  This strikes me an almost Orwellian reversal, since I would say: “You (coworker) are not a kindergartner anymore. Don’t make me read your 50 garbage commits like ‘checkin’, ‘try it out’, ‘go back’, etc, when the amount of changes you have merits 3 clean commits. Have the basic professionalism to spend 5-10 minutes to organize and communicate clearly the work you have actually done to your current and future coworkers.” I am no more interested in this “true history” than I am interested in the 5 intermediate drafts of the email memo you just sent out.

                                  1. 2

                                    Don’t make me read your 50 garbage commits …

                                    It sounds like we are no longer discussing Fossil, but a way of using Git where you do not use rebase.

                                    Here’s what the Fossil document says:

                                    Git puts a lot of emphasis on maintaining a “clean” check-in history. Extraneous and experimental branches by individual developers often never make it into the main repository. Branches may be rebased before being pushed to make it appear as if development had been linear, or “squashed” to make it appear that multiple commits were made as a single commit. There are other history rewriting mechanisms in Git as well. Git strives to record what the development of a project should have looked like had there been no mistakes.

                                    Fossil, in contrast, puts more emphasis on recording exactly what happened, including all of the messy errors, dead-ends, experimental branches, and so forth. One might argue that this makes the history of a Fossil project “messy,” but another point of view is that this makes the history “accurate.” In actual practice, the superior reporting tools available in Fossil mean that this incidental mess is not a factor.

                                    Like Git, Fossil has an amend command for modifying prior commits, but unlike in Git, this works not by replacing data in the repository, but by adding a correction record to the repository that affects how later Fossil operations present the corrected data. The old information is still there in the repository, it is just overridden from the amendment point forward.

                                    My reading is that Fossil permits you to view a “clean” history of changes due to its “superior reporting tools” and the “correction records” added by the amend command. But unlike Git, the original commit history is still recorded if you need to see it.

                                    1. 1

                                      My reading is that Fossil permits you to view a “clean” history of changes due to its “superior reporting tools” and the “correction records” added by the amend command. But unlike Git, the original commit history is still recorded if you need to see it.

                                      Ok that is interesting… I had been assuming that they were dismissing the value of clean history, but it seems they are not, but instead solving the same problem but at a different level in the stack.

                                    2. 1

                                      By this line of reasoning, why is the fossil commit the unit of “real history”? Why not every keystroke? I am not just being facetious. Indeed, why not screen record every editing session?

                                      That’s what Teleport is for. Other tools obviously also do this.

                                      More generally, stuff in the commit tree will eventually make it to production and run against real data and possibly hurt people. The stuff that can hurt people needs to be tracked. The ephemeral stuff in between doesn’t much matter. If I was purposefully negligent in my code, no amount of ephemeral work would prove it, there would be some other mechanism in place to prove that (my emails to a co-conspirator maybe, recording me with that evil spy, etc).

                                      Given that the fossil commit has been deemed the unit of history, doesn’t this just encourage everyone to big-batch their commits? Indeed, perhaps even use some other mechanism to save ephemeral work while I spend hours, or even days, waiting for my “official work” to be done so that I can create clean history?

                                      Why do you need to commit ephemeral work? what is the point?

                                      Have the basic professionalism to spend 5-10 minutes to organize and communicate clearly the work you have actually done to your current and future coworkers.”

                                      LOL fair point :) But that goes back to the previous comments, what is the purpose of committing ephemeral work? From my perspective there are 2 general reasons:

                                      • Show some pointy haired boss you did something today
                                      • Share some code in progress with another person to help solve a problem, code review, etc.

                                      The 1st, no amount of code commits will solve this, it’s either trust me or come sit next to me and watch me do stuff(or screen record, video record my office, etc). If my boss doesn’t trust me to be useful to the organization, I’m at the wrong organization.

                                      The 2nd, is easily solved in a myriad of ways, from desktop/screen sharing, to code collab tools to sharing Fossil patch files around.

                                      I truly don’t understand the point of committing half-done work like Git proponents seem to think is an amazing idea. A commit needs to be USEFUL to be committed. Perhaps it’s part of a larger body of work, it’s very common to do that, but then it’s not ephemeral, you are doing a cleanup so you can then implement $FEATURE, that cleanup can happily be it’s own commit, etc.

                                      But committing every nanosecond or on every save is just idiotic from my point of view. If you want that sort of thing, just run against a versioned file system. You can do this with ZFS snapshots if you don’t want to run a versioned file system. Git is not a good backup tool.

                                      1. 4

                                        I think this is fundamentally a workflow difference.

                                        Proponents of git, myself included, use committing for many purposes, including these prominent ones:

                                        1. A way to save partially complete work so you don’t lose it, or can go back to that point of time in the midst of experimentation.
                                        2. A way to share something with a co-worker that will not be part of permanent history or ever merged.

                                        The 2nd, is easily solved in a myriad of ways, from desktop/screen sharing, to code collab tools to sharing Fossil patch files around.

                                        Yes, I suppose there are other ways to solve the sharing problem. But since we do everything in git anyway and will have a PR in Github anyway, it is very convenient to just commit to share, rather than introduce a new mechanism for sharing.

                                        I truly don’t understand the point of committing half-done work like Git proponents seem to think is an amazing idea. A commit needs to be USEFUL to be committed.

                                        Sharing code to discuss and backing up milestones of incomplete, experimental are both very useful to me.

                                        1. 1

                                          I think the disconnect is probably in what we consider “ephemeral.” You seem to think that we’re “idiotically [. . .] committing every nanosecond” (which, seriously, stop phrasing it like this because you’re being an asshole), but in most of my own use cases it’s simply a matter of wanting to preserve the current state of my work until I’ve reached a point where I’m ready to construct what I view as a salient description of the changes. In many cases this means making commits that roughly match the structure I’m after - a sort of design sketch - and maybe these don’t include all of the test changes yet, and I haven’t fully written out a commit message because I haven’t uncovered all the wrinkles that need ironing as I continue the refactor, and I find something later that makes more sense as a commit in the middle because it relates directly to that other block of work, and and and…

                                          An example: when I reach the end of the day, I may want to stash what I’m working on or - depending on the amount of work I’ve put in - I may want to push up a WIP commit so that if something happens on my workstation that I don’t lose that work (this is always a real concern for reasons I won’t go into). Maybe that WIP commit doesn’t have tests passing in it, and I and my team try to follow the practice of ensuring that every commit makes a green build, so I don’t want that to be the final version of the commit that eventually makes it into the main branch. The next day I come in, reset my WIP commit and add the test changes I was missing and now make the actual commit I want to eventually see pushed up to the main branch.

                                          I don’t know of anybody who thinks saving things in WIPs for untangling later is - as you say - “an amazing idea,” but it’s a natural extension of our existing workflow.

                                3. 6

                                  I use both Fossil and Git at work, although we are almost done with moving all the Fossil repos to Git.

                                  Fossil is fine, but the immutability is kind of annoying in the long term. The lack of a rebase for local work is a drag.

                                  Its biggest problem is tooling. Nothing works with it. It doesn’t integrate with the CI system without a lot of effort, there’s no Bitbucket/Github-like system to use for PRs or code reviews, and it doesn’t integrate with the ticket system. Sure, it contains all those things, but they don’t meet the needs we (and most others, it seems) require.

                                  On a personal note, I dislike the clone/open workflow as I’d much rather have the database in the project directory similar to the .git directory. There are other little things I don’t like, but they are mostly because I’m used to Git, despite all its flaws.

                                  1. 3

                                    I would argue it’s because your perspective around Fossil is wrong when it comes to immutability. Fossil’s perspective is when you commit, it’s literally a commitment, it’s done. Be careful and think about your commits. Practically the only thing we have noticed is occasionally we get ‘oops fixed typo’ type commits.

                                    I agree with the clone/open workflow, but it’s that way for a reason, the perspective is, you clone locally once, and you open per branch/feature you want to mess with. So a cd is all you need to switch between branches. Once I figured that out, I didn’t mind the workflow that much, I just have a ~/fossil dir that keeps all my local open projects, and otherwise I mostly ignore that directory.

                                    I agree with the tooling problem, though I don’t think it’s quite as bad as you think. There is fossil patch for PR/code review workflows. The only special tooling fossil gives you here is the ability to copy and apply the patch to a remote SSH host. Perhaps that could be changed, but it allows you to develop your own workflow if you care about those sorts of things.

                                    I have a totally different perspective than the entire industry around CI/CD. CI/CD is just a specialization of running batch jobs. Since we have to run batch jobs anyway, we just use our existing batch job tooling for CI/CD. For us, that means our CI/CD integration is as simple as a commit hook that runs: nomad run <reponame.nomad> After that our normal nomad tooling handles all of our CI/CD needs, and allows anyone to start a CI/CD run, since it’s all in the repo, there is no magic or special tooling for people to learn. If you have to learn how production works anyway for batch jobs there is no sense in learning a diff. system too.

                                    1. 2

                                      It’s not just about perspective. I’m firmly in the mutable history camp, because a lot of my work - the vast majority of it, really - is experimenting and research. It’s all about coming up with ideas, sharing them, seeking feedback, and iterating. Most of those will get thrown out the window after a quick proof of concept. I see no point in having those proof of concepts be part of the history. Nor will I spend considerable time and effort documenting, writing tests and whatnot for what is a proof of concept that will get thrown out and rewritten either way, just to make the history usable. I’d rather just rearrange it once the particular branch is being finalised.

                                      Immutable history is great when you can afford it, but a huge hindrance when you can’t.

                                      With git, both can be accomplished with a little care: no force pushes to any branch. Done.

                                      What one does locally is irrelevant. Even with Fossil, you will likely have had local variations before you ended up comitting it. The difference with git is that you can make local snapshots and rearrange them later, using the same tool. With Fossil, you would have to find some other way to store draft work which is not ready to become part of the immutable history.

                                      I mean, there’ve been many cases over my career where I was working on a thing that became a single commit in the end, for days, sometimes even weeks. I had cases where that single commit was a single line changed, not a huge amalgamation or anything like that. But it took a lot of iteration to get there. With git, I could commit my drafts, share it with others, and then rewrite it before submitting it upstream. I made use of that history a lot. I rolled back, reverted, partially reverted, looked at things I tried before, and so on. With Fossil, I would have had to find a way to do all that, without comitting the drafts to the immutable history. It would have made no sense to commit them - they weren’t ready. Yet, I still wanted to iterate, I still wanted to easily share with colleagues.

                                      1. 3

                                        Clearly you and I are going to disagree, but I would argue that Fossil can handle your use-case just fine, albeit very differently than Git would handle it. You have clearly gotten very use to the Git workflow model, and that’s fine. That doesn’t mean the Fossil workflow model is wrong or bad or evil or anything, it’s just different than Git’s, because (I’d argue) it’s coming from a different perspective.

                                        Fossil does have ways to store draft work and ship it around, I mentioned two ways in the comment you are replying to, but you either didn’t see them or just chose to ignore them. fossil patch is actually pretty cool, as the patch file is just a sqlite3 file. Easy to ship/move/play with.

                                        1. 2

                                          I wasn’t saying the Fossil model is bad - it isn’t. It’s just not suitable for every scenario, and I have yet to see what benefit it would have over the mutable model for me. Just because it can handle the scenarios I want doesn’t mean it’s easy, convenient or straightforward to do it. Git can do immutable workflows too, and mutable ones too - it just makes the latter a lot easier, while the former possible if you put in the work.

                                          I did not see your comments about fossil patch before, I skipped over that part of your comment, sorry. However, that’s not suitable for my workflow: I don’t need a single patch, I can ferry one around easily, that wouldn’t be a problem. I work with branches, their history important, because I go often go back and revert (fully or partially), I often look back at things I tried before. That is important history during drafting, but completely irrelevant otherwise. Git lets me do dirty things temporarily, and share the refined result. Fossil lets me ferry uncomitted changes around, but that’s so very far from having a branch history. I could build something on it, sure. But git already ships with that feature out of the box, so why would I?

                                          I could, of course, fork the repo, and do my draft commits in the fork, and once it reaches a stage where it’s ready to be upstreamed, I can rebuild it on top of the main repo - manually? Or does Fossil have something to help me with that?

                                          I’m sure it works in a lot of scenarios, where the desire to commit often & refine is less common than think hard & write only when it’s already refined. It sounds terrible for quick prototyping or proof of concepts (which are a huge part of my work) within an existing project.

                                          1. 2

                                            Fossil really is just a fancy UI and some tooling around a SQLite database. There is basically no end to what one can do when your entire code tree is living in a SQL database. You don’t need 100k confusing git commands, when you literally can type sqlite3 <blah.fossil> and do literally anything you want. If fossil will understand it for you after is of course an exercise left to the SQL writer. :)

                                            That is important history during drafting, but completely irrelevant otherwise.

                                            Fossil has a different perspective here. All history is important.

                                            I think the big difference here is, Fossil’s UI and query tools are vastly more functional than Git’s. Literally an entire SQL implementation. Meaning you can hide/ignore loads of stuff from the history, so that in practice most of this ‘irrelevant history’ can be hidden from view the vast majority of the time.

                                            I could, of course, fork the repo, and do my draft commits in the fork, and once it reaches a stage where it’s ready to be upstreamed, I can rebuild it on top of the main repo - manually? Or does Fossil have something to help me with that?

                                            Yes, see: https://www2.fossil-scm.org/home/doc/trunk/www/branching.wiki

                                            No need to fork, a branch should work just fine.

                                            1. 2

                                              Fossil really is just a fancy UI and some tooling around a SQLite database.

                                              Similarly, git is just an UI over an object store. You can go and muck with the files themselves, there are libraries that help you do that. If git will understand it for you after, is an exercise left for whoever mucks in the internals. ;)

                                              Fossil has a different perspective here. All history is important.

                                              And that is my major gripe. I do not believe that all history is important.

                                              Meaning you can hide/ignore loads of stuff from the history, so that in practice most of this ‘irrelevant history’ can be hidden from view the vast majority of the time.

                                              It still takes up space, and it still takes effort to even figure out what to ignore. With git, it’s easy: it simply isn’t there.

                                              No need to fork, a branch should work just fine.

                                              According to the document, a branch is just a named, intentional fork. From what I can tell, the history of the branch is still immutable, so if I want to submit it upstream, I would still need to manually rebuild it first. Fossil maintains a single DAG for the entire repo (so the linked doc says), so if I wanted to clean things up before I submit it upstream, I’d need to rebuild by hand. With git, I can rebase and rewrite history to clean it up.

                                              1. 2

                                                I do not believe that all history is important.

                                                Seconded.

                                                We do not have to remember everything we do.

                                          2. 1

                                            Can you explain a little bit more how things like code reviews work? I’m not skeptical that they can’t be done in fossil, it’s just that the workflow is so different from what I’m used to.

                                            1. 2

                                              I am by no means a Fossil expert, but I’ll give you my perspective. Fossil handles moving the code back and forth, the rest is up to you.

                                              I work on a new feature and am ready to commit, but I want Tootie to look it over(code review). If we have a shared machine somewhere with SSH and fossil on it, I can use fossil patch push server:/path/to/checkout and push my patch to some copy for her to look at. If not I can fossil patch create <feature.patch> and then send her the .patch file(which is just a sqlite3 DB file) via any method.

                                              She does her review and we talk about it, either in Fossil Forums or Chat, or email, irc, xmpp, whatever. Or she can hack on the code directly and send a new .patch file back to me to play with.

                                              Whenever we agree it’s good to go, either one of us can commit it(assuming we both have commit rights). See the fossil patch docs.

                                    2. 1

                                      What do you mean of “the same data structure as git”, you know Fossil is using SQLite? I don’t know what the current Git data structure is, but from my experience with it, it is much more complicated to do something with compared to a SQL database.

                                      1. 2

                                        From the link under heading 2.3:

                                        The baseline data structures for Fossil and Git are the same, modulo formatting details. Both systems manage a directed acyclic graph (DAG) of Merkle tree structured check-in objects. Check-ins are identified by a cryptographic hash of the check-in contents, and each check-in refers to its parent via the parent’s hash.

                                        1. 1

                                          A merkle tree of commits containing the file contents.

                                        2. 1

                                          I’ve been using Fossil for my personal projects since summer 2020.

                                          The main advantages I see compared to git is that it is fairly easy to backup/move to a new server (the repository is just a single SQLite database and not a folder of a custom key/value format), as well as to give other contributors commit access (no shell access required).

                                          Beside this, I’m also more inclined to their philosophy of being immutable, as I would otherwise spent way too much time making my commits looks nice.

                                        3. 4

                                          The best design choice I can say about Fossil is using SQLite. The Git data structure is much more complicated and magic-like compared to a good-old database with SQL. Fossil is not integrated with almost any tool, but the design choice is something more software architects need to learn.

                                          1. 1

                                            The table schemas and whatnot might be simpler than the git object store (though, the git object store isn’t very complicated), but SQLite is very much not simple. Not its query engine, not its on-disk format - they’re all quite complicated, more so than Git.

                                            (Git does not include a bytecode engine, SQLite does.)

                                            1. 3

                                              But SQLite is a standardized, well-known, well-documented and well-tested tool, that has been widely deployed and is even recommended by the US Library of Congress for long-term storage. git(5) is reinventing the wheel here IMO.

                                              1. 3

                                                Exactly. It all comes down to the interface. SQLite and Fossil can be used with a little simple SQL. What about Git? You will need to have a degree on that or search everything you need.

                                          2. 2

                                            My largest struggle with Fossil, when I went through a stint of using it, was that it seemed to struggle with operations in repos that had large binaries, more than even Git did.

                                            Of course, self-hosting it is more work than keeping a repo on your code forge of choice.

                                            It’s cool, but it’s also niche. If you’re okay with niche, and supplying extra work for stuff like CI/CD, it can be useful for small teams.

                                            1. 2

                                              Is there any larger FOSS projects that is currently using Fossile for their version control? I’m curious to see how this works for external contributors.

                                              1. 5

                                                The obvious FOSS project using Fossil is SQLite. And Fossil itself. :-)

                                                1. 4

                                                  TCL/TK uses Fossil too.

                                                  1. 4

                                                    Perhaps not “larger,” but Retro Forth uses Fossil.

                                                    1. 2

                                                      I’ve been happy with Fossil, but my workflow has me as a gatekeeper. I accept patches (and/or modified source files directly), review, revise if necessary, and then merge them. At this point I’m the only one with access to push changes to the primary repository.