90 comments

[ 3.8 ms ] story [ 137 ms ] thread
In my books its a minus that you can not rewrite history. What happens if you accidentially add code where you dont own the copyright? Or an API Secret?

Having Tickets, the Wiki and technotes in the same place is an interesting idea, but doesnt seem terribly valuable to me. It seems to violate the unix philosophy, as in it does more than is needed. I rather have a lightweight versioning control system, another lightweight ticketing system etc., than one system which does it all.

> In my books its a minus that you can not rewrite history.

Yeah. Here Mercurial has a very good idea. It records which commits are public and immutable and which commits are drafts and editable. A draft becomes immutable once published, but public commits can always go back to being drafts with a --force, incurring an "everyone out of the pool" scenario.

There's nothing wrong with rewriting commits as long as everyone agrees where the boundary lies between published history and drafts. For git, this boundary is often set by a convention such as this: rewrite feature branches all you want, but master must never be rewritten.

> In my books its a minus that you can not rewrite history. What happens if you accidentially add code where you dont own the copyright? Or an API Secret?

Someone will write the necessary scripts (e.g. fossil-rebase) to go into the DB and rewrite history.

Yes, but then you are fighting the software, and it wouldnt need to be immutable at all if you can change it anyway
> Someone will write the necessary scripts (e.g. fossil-rebase) to go into the DB and rewrite history.

No, they won't. The fossil file format is very strongly protected against any changing of history. Changing history changes multiple hashes (at multiple levels) and breaks it. Immutable history is literally part of the metadata specification, and the db is "just a data store," independent of that specification.

Git is the same, if you rebase many hashes will be recalculated, and the "tampering" would be obvious to anyone who had a copy of the repository. It is possible to implement the equivalent of rebase in any distributed VCS, the authors of Fossil simply chose not to. If it becomes more popular, somebody else likely will.
i've been on the fossil dev team since 2008, and i have seen many people claim that it "could" be compromised/modified post facto, and yet... nobody has been able to do it. Fossil's core data model does not just _assume_ that history doesn't change - it makes it essentially impossible to do.

Shunning is a special case which removes a given artifact from the db, but is considered a "nuclear option" of last resort. i've never personally used it.

From what I just read, the "shun" method means that you can rewrite history by adding a shun, rebuilding a copy, then switching copies.

Not db rewrite, but the same end result.

edit: bad english

That won't work because the SHA1 hashes won't match up.

If you accidentally check-in proprietary or sensitive content that you didn't mean to publish, you can shun that content. Shunning leaves a hole in your history. There is no way to replace that hole with different content.

> Having Tickets, the Wiki and technotes in the same place is an interesting idea,

Couldn't you just have a `bugs`, and `notes` branch? gugs would be a folder per bug, with each message being a MIME or some similar message format. notes would be a collection of md, rst, textile, &c similar to how github already has a gh-pages branch. It wouldn't need to be part of the scm, but simply be convention.

This sounds horrible. Why would you think this is something people should be subjected to? The polar opposite of user friendly.
The user interface is a separate concern from the serialisation format.
1) I never even mentioned a UI or how the user would interact with what I proposed.

2) Even if you just edited files with a text editor, how is that not user friendly? It's about as friendly as it could possibly be.

The benefit to having it in the same branch/associated with a specific branch of code is that it makes it easier to have those issues and notes represent the current state of that branch and as you merge branches for that information to similar flow across the merges just as with the associated code.

For example, say you fix a bug in a specific branch. If the issue is being tracked inside that branch you can mark it as fixed in that branch, and then checking if an issue is fixed in a given branch is a matter of checking the issue state for that branch. As you merge that code change to other branches, the flag that the issue has been fixed presumably flows with the merge as well and you have an easier time of telling the particular state of any given branch.

What happens if you accidentially add code where you dont own the copyright? Or an API Secret?

http://fossil-scm.org/index.html/doc/trunk/www/shunning.wiki

So… not that different from git after all? (rebasing creates new revisions, but while the old ones may not be trivially accessible anymore they're still there until garbage collected)
Rebasing can move whole subtrees around in the repo's history, then publish all those changes back to the repo you cloned from. There is nothing like this in Fossil, on purpose.

Fossil's shun operation and private branches are entirely different from rebasing.

First, shunning: that just nukes a particular artifact from the local repo, leaving a hole in the history. You can't push a shun operation to another repo, and if you do the shun on a central repo, any clones of it that were made before the shun don't copy the shun record, so they keep their local copies of the shunned artifact. The only way to propagate a shunning operation through a clone network is cooperatively: you have to ask everyone to agree to shun that artifact in their local clones, then rebuild their repositories.

As for private branches being a "history rewriting" mechanism, that's nonsense. Changes made to a private branch are never part of the history on the repo you cloned from in the first place. They're analogous to the default working mode of Git, where your checkins aren't immediately sync'd to the repo you cloned from. If you never sync, or you purge your local changes, history doesn't get rewritten, the changes just never become part of the official history in the first place.

> Rebasing can move whole subtrees around in the repo's history

Rebasing does not move subtrees, it copies them.

> Fossil's shun operation and private branches are entirely different from rebasing.

Well considering they apparently genuinely destroy things, quite so.

Rewriting history was considered Very Bad by most everyone who had not yet used distributed version control much. The set of people that had not yet used distributed version control much included everyone, even the developers of distributed version control tools. After we all started using DVCSes more we realized how useful and powerful it was to be able to rewrite local history.

Fossil developers are apparently still catching up to this idea but as pointed out in other replies here it does have some history rewriting features. Even its recommendation that you pull and merge others' changes with yours before you commit your changes (in the style of CVS or SVN, they call it "autosync") is a form of rewriting history. See: http://fossil-scm.org/xfer/doc/trunk/www/concepts.wiki

Yeah ... the key here is the qualifier "local".
You can always rewrite history, just do a replay into a snapshot of the repository (modifying the system time, or noodling the app to inject the timestamps you want).

I guess you could arrange for some trusted external time authority to sign hashes of commits. That'd be interesting.

> In my books its a minus that you can not rewrite history.

To quote Richard Hipp, the primary author of Fossil and SQLite [1]:

"Fossil, in contrast, is designed to remember everything. Fossil was specifically designed to support the DO-178B inspired development process used by SQLite, with few developers and a complete and immutable audit trail for all inputs."

About DO-178B: https://en.wikipedia.org/wiki/DO-178B

In short: Fossil is designed for a different purpose than Git.

Note that even then, in Fossil – as with every system that represents data in purely electronic format – nothing is truly immutable. And Fossil does have ways to excise data from history (shunning, "fossil purge", etc.). You can even run raw SQL queries on the underlying SQLite database if you want or use "fossil deconstruct/reconstruct" to break down a repository into its constituent artifacts and rebuild it. However, these are generally methods of last resort and there are no frontend facilities to easily integrate them into your workflow (other than, arguably, "fossil purge", which is local only).

[1] https://www.mail-archive.com/fossil-users@lists.fossil-scm.o...

This is a wonderful idea. The VCS, bug tracker, wiki, and web presence really should all be part of a packaged deal.

Almost nobody uses just git -- they use github or gitlab. Very few people use Mercurial, because there is nowhere good to host it. Atlassian seems hell-bent on killing hg support off bitbucket, because few people use it, a very sad self-fulfilling prophesy.

With offerings like gitlab, it might not make a huge difference, but contenders like Fossil or hg have some good non-git ideas worth exploring.

> Almost nobody uses just git -- they use github or gitlab.

I don't understand what you mean. I know plenty of people that simply use SSH or local-only repositories. If you intend on sharing said repo, github is essentially cheap shared hosting (or did you also complain that people didn't run their own httpd?).

  I know plenty of people that simply use SSH or local-only 
  repositories.
These people are the minority. Do you know at least 3 million people who use git without github? If not, you're nowhere near to saying that a majority of git users do not use github. And yes, having somewhere to host it is very important. Both Fossil and hg have an httpd built-in. I believe cgit or gitweb are not a simple "git serve" away?
We don't know how many people are using SSH git but you surely know they are much less than 3 million.

Have you heard about Dunning-Kruger effect?

Yes, I assume you are indicating that I think my skill is greater than it actually is? Which skill are you referring to? Or whose skill are you referring to?
You are too sure of your conclusion without a justification.

Neither I nor you know 3 million people and their habits. Yet you are certain there is no such a group of 3 million people that will contradict your conclusion.

It's not about your skills. It's about your confidence based on nothing.

> Do you know at least 3 million people who use git without github?

Why must one have never used github while also not using github? I have many private repos I share amongst my machines, but I also publish projects on github when I want them to be public.

> Both Fossil and hg have an httpd built-in.

That seems horrible. Why do I want these features built in when they can be delegated to other applications (which I can choose among based on their features and not forced to use the one supplied?)

You can use another httpd if you want to. It's just nice to have one built in if you don't.
Why add the complexity to the scm? That's not its job.
> Almost nobody uses just git -- they use github or gitlab.

Your points are made in a needlessly provocative manner.

Tons of people roll their own interfaces to their source control, and a lot of people benefit from somewhat centralized repositories. Not only is there room for both, but I don't see any data indicating how prevalent private, non-GitHub repositories are, or how those would even be counted accurately given the distributed model

Almost nobody? Very few people use Mercurial? Nowhere good? Hell-bent on killing? Few people use it? very sad self-fulfilling prophesy? Jeez, there's opinionated, then there's recklessly authoritative. Mercurial isn't as popular as git, but neither are dependent on GitHub/bitbucket for continued relevance.

To address your point more directly, I personally think that merging the concepts of versioned data and developer tasks makes for less flexibility; I prefer simple, pluggable, and modular to integrated when it comes to version control.

The approach that I am taking is (at the moment) highly integrated -- and that is the thing that I am most concerned about -- I'd rather like to find a way to turn it into a set of disparate tools that use common (open) interfaces to work together -- But I haven't found a way to navigate towards that just yet.
> Tons of people roll their own interfaces to their source control,

And how do they compare with github's megatons? I argue the numbers are not comparable. My most generous estimate is that less than 5% of all git users work without ever touching Github.

> Mercurial isn't as popular as git, but neither are dependent on GitHub/bitbucket for continued relevance.

I am convinced that if anything ever replaces git, it will have to come with a website that greatly simplifies deploying software. Git alone is not enough for sharing with the masses -- it requires Github or equivalent. I am also certain that git's meteoric rise would have been completely impossible without Github.

Every time I see a newcomer trying to deploy a Mercurial repo, I see them struggling with Bitbucket's implementation of hg hosting. It pains me that there is nothing better to direct them to.

I'd say "users that never use Github, for anything" isn't a very useful measure. Yes, that number is very low, but I bet most of GitHub's users also have repos that do not exist on Github, or are only sent to GitHub as a mirror (because GitHub is where people search for code).

  I'd say "users that never use Github, for anything" 
  isn't a very useful measure.
It is important because Github has become the yardstick by which everything else is measured. People expect git to work roughly like Github. The whole pull request workflow was popularised by Github. Linux and git do not use pull requests. The deprecation of the git:// uri scheme is also Github. The expectation of an integrated bug tracker, comment threads, and wiki is also Github.
That is by far the biggest attraction for me (to use fossil). Part of me doesn't like having all those pieces combined into one tool, but after the Google Code shutdown, I've realized you can't rely on external hosting to keep your code.
> Git does not care about history, you can rewrite it as you feel like (git rebase). On the other hand, Fossil is immutable. Audit is possible, every action leaves a trail, and you can not rewrite it.

Ehm, That's not a fair assessment. Git is as much immutable as fossil.

In fossils case, I can still poke around the sqlite database and delete rows from it. That may be difficult to pull of, because I expect the internal data model to be quite complicated, but certainly not impossible.

I don't understand the hate against rebase. Nobody uses it with malicious intent. And, those who do, will have no problem working around fossil's immutability.

> Ehm, That's not a fair assessment. Git is as much immutable as fossil.

I'm not familiar with fossil, but in git if update my HEAD and the REMOTE head isn't a simple fast-forward I get an error. So while the repo's history isn't immutable, each individual commit (and its history) _is_ immutable (modulo sha1 hash collisions).

What is the value in having history be static? I find that rebase comes in handy as I'm working locally, commit an absurd number of commits in stream-of-programming style, and then go back and clean it up before pushing to the shared repo. What is the analogous workflow in fossil?

> What is the value in having history be static?

auditability, for one. Certain business processes, e.g. those sending people and machines into space, require 100% immutable auditability.

That's something you can easily attain in Git as well, your central repository just denies non-fast-forwards, which gives you exactly what fossil is giving you.

What fossil is denying you is the ability to rewrite all history for whatever reason, whether that's because you want to squash multiple commits or have decided (after audits etc.) that you really want to rewrite your central history and start anew.

Nobody needs audibility on unfinished work that hasn't been pushed to the central repositories (and would thus be protected by non-fast-forward).

To the extent that you would fossil doesn't make the situation better, if I can't fix up my commits after the fact before I push them I'm just not going to make those intermediate commits in the first place, which gives the system no more information to work with, and results in a less convenient workflow for me.

This whole "we preserve history forever" statement is a red herring. They've just picked a data model which is hard-immutable, but it doesn't mean that they're categorically preserving more information, or that tools that have configurable-immutable datamodels (like Git) preserve less history in practice.

Why do you feel that you _have_ to be able to correct history? The past is immutable. Fossil treats it as such. git does not, no matter what configuration you're running - i can always create a fork, modify the history in my fork, and publish that. git has mutable history, period. fossil does not, period. They are different mindsets. i personally don't mind my mistakes staying in the record, and i am suspicious of people who feel they need to retroactively cover up past mistakes.
> Why do you feel that you _have_ to be able to correct history?

Why do you feel I shouldn't be able to do what I want with my history before others see it? Shared repos can reject history rewrites, as the parent said.

Also, as others have said, fossil does not provide the tools to mutate history, but that doesn't mean that history is immutable.

> They are different mindsets. i personally don't mind my mistakes staying in the record, and i am suspicious of people who feel they need to retroactively cover up past mistakes.

Who's talking about mistakes? I'm talking about cleaning up a stream of small commits I've made over the day into a smaller number of coherent, sensible commits.

"Mistakes" was indeed a poor choice of words, but the principle is the same: fossil does not allow the public record (mistake or otherwise) to change, with the one exception of the "nuclear option" (shunning, which forcibly removes content from the repo).

git allows the public record to be flexible forever. "History is written by the victors." Fossil believes that everything in the repo is in the public record and that the public record must never change. "History is recorded as it happened."

> fossil does not allow the public record (mistake or otherwise) to change,

But you can do the same in git -- the shared repo can reject non fast-forwards. This allows you to rebase your _private_ history and enforces consistency off the share. Granted, in a peer-to-peer model this is less useful, but that isn't how most teams work nor is it how a team that needs immutable history would work.

uh, this is a very pessimistic view on history rewriting.

Much more common probably is the fact that one tries to persist very gradually local changes, and once the dust has settled, submit a much coarser commit. Because most of the time all these "fixup this", "add missing imports" commits are really of nobodies interest any more.

If you hold on to a git hash, you are can identify history changes very easily.

> Why do you feel that you _have_ to be able to correct history?

We need to distinguish between published history (that was pushed to a central repository) and local history on my laptop. Nobody wants to correct published history.

The argument about the audit trail is nice. But compare the value of a single, atomic commit with a long and detailed commit message about what it does (like the ones you see in the linux kernel), with a dozen or more small commits which the developer did while working on that feature, each of which most likely has just some nonsense text as the commit message.

If you really see the value of preserving every single individual step which the developer has taken, you should record every keystroke, so that you capture every mistake and typo and all the intermediary states of the source code. Or go even further and record every conversation, meeting and all the coffee breaks chats which may or may not be relevant to the feature the developers are just now working on.

Nobody wants to correct published history. Yet it still happens. Not that long ago at my office I pulled updates via git to what is to me a read only repo. I never make changes to it. Yet after pulling updates, my repo was in a state claiming I had changes to commit. The whole problem was someone who did rewrite published history. In my case the 'fix' was easy. Delete my clone and reclone. If it had been a project I needed to commit to as well, I doubt fixing the problem would have been nearly as straightforward.

Sure, "rewriting history" with fossil could be done by anyone with sufficient skill and patience. The lack of such functionality as "first class features" of the software mean that it is unlikely to happen.

You lay the burden to ensure that you can't make mistakes (rewrite history) on the developers of fossil. If, for some reason, fossil allowed to rewrite the history it would be considered a bug and promptly fixed. Yet, for some reason, you don't expect the same from the sysadmins who set up the git repository (ie. set it up so that non-fast forward updates are rejected).

We can debate whether Git's default is sensible or not.

I'm not sure I understand what you're getting at. Sure I expect sysadmins to configure things properly. I also expect people to be human and make mistakes. My only point was that despite everyone's best intentions, it can still happen and it can be a pain to fix. If the functionality was not there, it would have been a non-issue.

Is fossil perfect? Is any software perfect? Of course not. I was merely describing a single pain point I recently experienced that would not have happened without the ability to make changes to published history.

Doing a pull like that would force a merge and would be very noticeable. Also, there are other, many other, options beyond the nuclear delete and clone.
Doing an update like that would force a merge, but there was nothing to merge. I made no changes. It was a read only (to me) repository. It should have just worked, and would have had someone else on the team not rewritten history.

I'm aware there are more options than delete and clone. My options were to spend time trying to fix my clone to which I had made no changes, or I could delete and reclone from the origin. The pragmatic solution was obvious and got me back to work more quickly than I would have otherwise been able to.

The fact that there are more options to allow fixing a broken clone are nice, but irrelevant. Had git not allowed removing published history, it would not have been an issue.

I'm all for the ability to amend history, which fossil does allow (to an extent). What it doesn't support deletion of old history followed by the creation of new history.

I'll reply to both this and your downstream comment here for simplicity.

    > Why do you feel that you _have_ to be able to
    > correct history? The past is immutable. Fossil
    > treats it as such.
Opinions differ on what aspect of the past should be made immutable.

Should we be recording every single one of your keystrokes in a commit?

How about just every time you hit "save" in your editor?

Git takes the view that making commits is just like hitting "save" in your editor, it's not inherently an operation you want to publish as-is.

You can just as well do this with fossil, whatever the tool's guarantees of immutability I can always just cp an older version of the directory to get around it and re-do my commits, which on some level is exactly what "git rebase" is doing.

Git just makes this process that people have a good reason to do more convenient. Just like I don't want to see every single one of your keystrokes or every one of your "save" snapshots when reviewing your code I have no reason to be reading hundreds of your "oops, compilation error" commits.

Of course I suspect that you don't get much of that with Fossil in the first place, because due to this idealism of immutable history people just aren't using the SCM except for "real" work.

Which I think sucks, Git has saved me multiple times with some bug I've introduced mid-editing session because I could bisect my 100 "another snapshot" commits, commits that I then subsequently rebased into 1-5 commits and pushed upstream.

    > Git allows the public record to be flexible forever.
This is just not at all the case in practice. With Git the difficulty of rewriting history increases as a function of how widely that history is published. Fossil proponents seem to think that established history is being regularly willy-nilly written by projects that use Git.

The mainline history of git.git, or linux-2.6.git etc. is not being rewritten and never will.

What is being rewritten is locally authored commits that haven't been pushed yet, or topic branches that get deleted and replaced by other versions (e.g. with typos fixed in commit messages etc.).

You can use Git like Fossil, but most people just choose not to because it doesn't make sense.

> Certain business processes, e.g. those sending people and machines into space, require 100% immutable auditability.

I work for a company that builds machines to be sent into space (specifically, electronics and high-tech instruments), and I have never heard of such a requirement. The end result matters to our customers, not the thousands of commits in our Subversion repository.

i don't know which business you work for, but i have it on good authority (from an unspecified sqlite core developer) that getting software into commercial airplanes requires 100% auditability of the source history. i _assume_ that's the same for space travel - maybe not, or maybe it depends on the context.
> What is the value in having history be static?

[Edited for formatting]

Section "3.9 Audit Trail" of "http://fossil-scm.org/xfer/doc/trunk/www/fossil-v-git.wiki" puts it best. It's about being able to audit the history, instead of using history as a kind of documentation of the intent of the changes:

    Git features the "rebase" command which can be used to
    change the sequence of check-ins in the repository. 
    Rebase can be used to "clean up" a complex sequence of
    check-ins to make their intent easier for others to
    understand. This is important if you view the history of 
    a project as part of the documentation for the project.

    Fossil takes an opposing view. Fossil views history as
    sacrosanct and stubbornly refuses to change it. Fossil
    allows mistakes to be corrected (for example, check-in
    comments can be revised, and check-ins can be moved onto 
    new branches even after the check-in has occurred) but
    the correction is an addition to the repository and the
    original actions are preserved and displayed alongside
    the corrections, thus preserving an historically
    accurate audit trail. This is analogous to an accounting 
    practice of marking through an incorrect entry in a
    ledger and writing a correction beside it.

    To put it another way, Git remembers what you should
    have done whereas Fossil remembers what you actually
    did.

    The lack of a "rebase" command and the inability to
    rewrite history is considered a feature of Fossil, not
    an omission or bug.
> What is the value in having history be static?

Because you can trust it. Rewritable history is like maintaining your business ledger on a whiteboard.

> I find that rebase comes in handy as I'm working locally

This idea that local development is a good thing is one of the biggest differences between Git and Fossil.

Git was created to serve the needs of the Linux kernel, where the development effort is not only distributed, but also federated, with islands of development sporadically pushing changes higher up the tree. You see this on Github, with semi-private forks of projects containing changes that never make their way back into the primary project. If that is the sort of project you're working on, Git is the right tool.

Fossil, however, is meant for much more cohesive teams. While it does allow one to go off on a tangent, developing for weeks at a time with no outsiders ever seeing what you're doing, that is not its default mode.

In Fossil's default mode, local checkins are immediately sync'd back to the repo you cloned from, which is typically the official central repo. Fossil allows you to have chains of repos (A clones from B, which cloned from C, which cloned from D...) but a simple 2-level fan-out is much more common.

I think of Fossil as a DVCS with the day-to-day workflow sensibility of Subversion.

The DVCS aspect means you can take your laptop to the mountains with you, code for a week in your tent while your relatives all enjoy the dubious pleasures of nature (the weirdos) then come back home and sync back up with the central repo, your whole change history being grafted back in as if you'd been autosyncing to it the whole time.

The Subversion sensibility means that while working in the office, every checkin normally becomes immediately visible to your team members, as do theirs to you. While this makes some people nervous — particularly those who have only used Git — it has benefits.

I can state those benefits in terms of the [Ten Commandments of Egoless Programming](http://goo.gl/13r3xT), published by Gerald Weinberg way back in 1971 as [The Psychology of Computer Programming](http://goo.gl/NqqGnl). Using his numbering:

1. You will make mistakes, but Git encourages you to hide them in the stash, in private branches, in changed checkin comments (git commit --amend), and in history rewrites. In its default working mode, Fossil pushes every checkin immediately back to the repo you cloned from, where they can be noticed and fixed ASAP. The longer an error goes unnoticed, the greater the damage it can do.

2. You are not your code. Private branches are a symptom of the sort of perfectionism that violates this commandment. You don't want to spend a week going off on a tangent when one of your colleagues could have saved you from wasting your time by seeing the path you started down with your first commit. Fossil has a way to create private branches, but unlike Git, it isn't the default mode. Defaults matter.

4. Don't rewrite other people's code without consultation. You've worked with that guy. You know, the one who runs the whole codebase through indent(1), the one who changes multi_word_function_names to camelCase, the one who "refactors" things endlessly. Git's default mode of working on a private branch, then pushing a bunch of work as a single bolus makes this sort of fiddling worse. Fossil's default autosync mode lets you detect that sort of thing early and nip it in the bud.

6. The only constant in the world is change. So, when a colleague makes a change in trunk that breaks your change-in-development, you want to pull it into your tree ASAP so you can fix up the problem before trying to merge your change in. You don't want to find out a week later when you and your colleague both try to check in week-old private branches, and fin...

> Because you can trust it. Rewritable history is like maintaining your business ledger on a whiteboard.

You can trust a git commit to never change.

> You will make mistakes, but Git encourages you to hide them in the stash, in private branches, in changed checkin comments (git commit --amend), and in history rewrites. In its default working mode,

That is not the purpose of any of those things, nor is the purpose to "hide" anything. The purpose is to make the history more understandable and give you the ability to compartmentalize changes. While you shouldn't be working on multiple things, I and most other people I met, end up doing so. Being able to split those into commits all about the same thing is handy.

> 2. You are not your code. Private branches are a symptom of the sort of perfectionism that violates this commandment.

It's not protectionist or perfectionist to keep non-working code out of the main branch. If I'm rewriting something, why should everyone else have a non-working version of it for the duration of the rewrite?

> Don't rewrite other people's code without consultation

You can't work on a project with other people without using their code, and often you _can't_ consult them. Sure, don't autoformat, &c. I don't see how private branches encourage of facilitate this. People will do what people will do. I've seen people do this in subversion, so I don't see your point.

> You don't want to find out a week later when you and your colleague both try to check in week-old private branches, and find that you'll need another day or two of work to fix up the differences.

I'm not sure what you're talking about as I've never had such a terrible merge in git (though I have in subversion).

> Don't be "the guy in the room." But Git wants you to be that guy. Before you can check a change in with Fossil, it first checks if there are any changes in the repo you cloned from, and makes you either say "fossil up" to pull them into your local repo, or check in on a branch. This encourages you to either test your changes against the tip of trunk before checkin in, or at least publish your changes as a branch so people can see you go haring off in a different direction, and maybe correct your trajectory.

You can't push a non fast-forward by default. (You can force, but that can be disabled and is heavily discouraged.) I'm not seeing why your model is inherently any better than make sure tests pass after a merge. Again, it's up to the dev, not the scm.

> Not all merge conflicts can be detected by the VCS's merge algorithm. Just because your changes merge cleanly into the central code repo doesn't mean you haven't broken the build, or the tests, or... Fossil encourages you to test your change against the tip of the branch you're working on before checking in.

Fossil does not, your build and project environments do.

> Git amounts to a social regression with respect to Egoless Programming.

I have no idea what you even mean. Git is about giving you the tools to make code changes that make sense, without the need to obtain someone's blessing over your code. All other decisions are yours and yours alone. I can not test in SVN, Fossil, CVS, Perforce, &c. I can edit other people's code as well. Nothing is stopping me but convention and what I decide to do.

> While you shouldn't be working on multiple things, I and most other people I met, end up doing so

Fossil solves that with branches. Merging a branch into the trunk is equivalent to what Git calls pushing. The difference is that everyone can see your branch, unless you use a private branch, which is more like Git. I've argued the advantages of working on a public branch already, though, so I won't repeat that here.

That reminds me of another big difference between Fossil and Git. With Git, the checkout tree and the local repo clone are tied up in a single directory tree. The normal way to switch branches is to check all of your local changes in, then switch the current working directory over to the other branch.

While you can do that in Fossil, too, because the repository is a separate file, when working with long-lived branches, it is easier to have separate checkout trees, one for each such branch. The advantage is that switching branches doesn't change all the timestamps for changed files, invalidating build artifacts and such.

To get the same effect with Git, you have to clone the whole repo for each long-lived branch, which complicates things greatly, and wastes a bunch of disk space.

> It's not protectionist or perfectionist to keep non-working code out of the main branch

So check it in on a feature branch or a private branch. Once the new feature in the branch functions as intended, merge it into the trunk.

> why should everyone else have a non-working version of it for the duration of the rewrite?

If it's a public branch, their Fossil pulls will indeed give them a copy of your branch, but they will only be able to see your checkin comments in the Timeline view, by default. That tells your team members what you're working on, which, as I've already argued, is a good thing. If they have concerns about your direction, they can switch to your branch (a la Git) or check it out into a separate working tree. Or, they can just ignore it, and let you get about your business.

> often you _can't_ consult them

I already stated it above: if you're working on a project where you're not really collaborating with people, and where haring off in your own direction is a normal thing, then Git may well be the correct tool for you.

Fossil is for coherent projects, where people are expected to work together. The SQLite project, which Fossil was created for, is an example of this: to join the project, you have to first impress someone enough to get a commit bit, then you sign the contributor agreement. You are expected to participate on the developer mailing list once accepted.

Fossil is also good for traditional corporate development, where those with commit bits are your coworkers.

> I don't see how private branches encourage of facilitate [rewriting other people's code]

Git's normal working model is that your checkins are local first, then only optionally pushed back to the repo you cloned from. I'd bet a whole lot of the forks on GitHub will no longer integrate back into the parent project. You can see this in the language they use: forking.

This is not necessarily a bad thing. If you need federated development, Git's your tool.

But if instead you're after collaborators, contributors, and coworkers, you don't want forking the repo to be the normal first step.

> I'm not seeing why your model is inherently any better than make sure tests pass after a merge.

The "guy in the room" spends days or weeks working on code without showing anyone what he's up to. Then there is a big-bang merge event, which may or may not succeed, and may wreck his coworkers plans.

If you ignore private branches in Fossil, you end up either working on the trunk, where your coworkers will immediately see your changes, or working on a public branch, where they're likely to at least see your checkin comments, and can look at your changes if they become concerned about your direction....

> > While you shouldn't be working on multiple things, I and most other people I met, end up doing so

> Fossil solves that with branches. Merging a branch into the trunk is equivalent to what Git calls pushing.

git does the same thing, though sometimes you're working on two related things, but want to make 2 commits.

> Git's normal working model is that your checkins are local first, then only optionally pushed back to the repo you cloned from.

Because I may not own or be associated with the original repository? Are you saying I shouldn't work on code simply because I can't contact the original author?

> The "guy in the room" doesn't ask for comment; he just drops his magnum opus into the trunk and says "deal with it."

But again, if i'm working on something that necessitates breaking something while it's being fixed, you're saying to use a private branch, so what's the difference?

> Because Fossil defaults to "autosync on", you can't check in a change on a branch that has upstream changes. Fossil simply won't allow it. (There's a "force" option, but it creates a special kind of branch called a fork, which has to be resolved at some point.)

Git has the same ability to prevent forced pushes. I'm still not seeing your point. But also, none of this actually solves the issue that everything you're talking about are environmental and not inherent in the scm, i.e. testing.

> This is why we have social mores and community standards of behavior. It is a good thing if the tools we use support those desirable behaviors.

The tools shouldn't stand in your way when you want to make a coherent idea a single idea instead of multiple little, sometimes conflicting ideas.

It seems to come down to if you believe you own your code and everyone should be "allowed" to work on your code, or if you believe that anyone should be able to work on code. (centralized vs federated).

> I may not own or be associated with the original repository?

Then you're doing federated development, and you should continue to use Git or another tool that supports that style of development as a first-class activity.

Many years ago, I read that > 90% of all software development is in-house private stuff. (Billing systems, custom workflow management software, etc.) A big chunk of the rest is software for sale by a company. If you have federated development going on within the bounds of a single company, you've probably also got organizational silos, which is a problem.

I suspect open source and SAAS have shifted that statistic in recent years, but I'd bet most software is still developed by a group of developers who all at least know each others' names, and can at least email each other, if not buttonhole each other at the water cooler.

Other shifts in the market, such as from boxed software on retail shelves to app stores is a net zero in this discussion, since the software is still developed the same way.

> It seems to come down to...centralized vs federated

Yes. The popularity of Git has associated "DVCS" with federated development, but one of the points I'm trying to make is that you don't have to give up on the benefits of a centralized repository if you need a DVCS.

> Then you're doing federated development, and you should continue to use Git or another tool that supports that style of development as a first-class activity.

So, let's say I want to work on an open source project done in fossil. Let's say I don't personally know anyone associated with the project, and kind of just want to play around with it and I'm not even sure I'll be able to fix any bugs or add any useful features, or I just want to hack on an idea I had. How do I do this? Private branches? Isn't that what git offers?

Sure, if there is never an expectation of an outsider looking at or hacking on the code, then a non-federated tool might make sense, but in any situation where the code is suppose to be public, I don't understand where the advantage is (or why I would ever voluntarily learn fossil unless as employer required it).

> let's say I want to work on an open source project done in fossil....How do I do this?

You clone the repo, open it into a working directory, and turn off autosync. Then all changes made to the repo affect only your local instance.

If you think there's a chance that you might want to send your changes back upstream, you should probably work on a branch. Then when it comes time to send your changes to someone with checkin rights on the repo you cloned from, you can use a feature that is unique to Fossil, as far as I know, called bundles. (http://fossil-scm.org/xfer/help?cmd=bundle) It is essentially a slice of the Fossil repository that someone else can integrate into their own repo, not unlike a pull request on GitHub.

I actually prefer to think of Fossil bundles as uber-patches, since they record not only the textual changes to the repo, but also file modes, the full checkin history, checkin comments, file removals and additions, etc. Basically, it fixes every weakness of patch(1).

> I don't understand where the advantage is

The advantages are listed on or linked from the front page of the Fossil web site: http://fossil-scm.org/

For me, the biggest single advantage is the simpler day-to-day working model, but maybe you will find another virtue that you prefer.

> Ehm, That's not a fair assessment. Git is as much immutable as fossil.

HA! HAHA! HAHAHA!!!!

For any reasonable definition of "immutable," git is most certainly NOT immutable.

A tree with a known hash will never change.
Being from Richard Hipp, the author of SQLite, it should be a pretty high quality program.
I really like the idea behind Fossil ... but on the other hand, I want to bring all development together into one homogeneous interface: I want to do almost everything without leaving Sublime Text.

For that reason, I am experimenting with storing all my documentation (requirements, plans, task lists etc...) as text files in a git repository, using YAML when I need structure, and markdown when I need formatting or something richer.

To tie everything together, I maintain a diary, which consists of one text file per developer per sprint. This diary holds allocated jobs to do each sprint, together with a record of what was done each day.

Because all of my work information is available in the repository as text (markdown or YAML or JSON) - it means that I can automate my workflow in ways that would be much harder to achieve otherwise.

For example, I can extract appropriate git commit messages automatically from this diary, meaning that I have perfect traceability back to requirements on every commit. I can get my build to (optionally) commit changes automatically (rolling back if the build was not successful). I can even get it to (again optionally) make sure that all changes associated with a particular job are kept on a separate branch until that job is complete. In other words, I have lots of options when it comes to tying my workflow together with my CMS/VCS in an automated and scripted way.

And all because I am too lazy to open my web browser to look at JIRA or Trac (or whatever).

:-)

It also means that -- because my "tickets" and "requirements" documents are just bits of YAML with a particular structure -- I can store tickets, requirements and so on pretty much anywhere in the repository - either in their own directories, or interspersed with and embedded within the source code as comments -- sort of like a TODO but with super-powers.
> sort of like a TODO but with super-powers.

Funnily enough our team just introduced an eslint warning (https://github.com/eslint/eslint/blob/master/docs/rules/no-w...) to discourage those TODO comments as we found they just always sat around forever collecting lint.

Similar here. If the todo survives the development branch, it should be moved into the ticketing system. Otherwise, you have two ticketing systems, one of which will be forgotten when it comes time to prioritize new development.
You are quite correct. It is always a bad sign if you have tasks that are captured but never actioned ... (Almost as bad as never capturing the problems in the first place)

However, it is just as easy to have unloved, unwatched tasks festering in JIRA or Trac as it is to have TODOs festering in the source code. (I've seen both). The form in which the problem manifests itself isn't terribly important here ... or at least, its' less important than the solution.

What is needed is a robust and active process to triage new issues; to action items that really are a problem, and to record the decision to discard problems which are not worth resolving. If you have this process in place and working, then you don't need to care as much about where the tasks are stored: SQL database or text file or Excel spreadsheet ... all can be made to work.

Now, personally, I would argue that having a structured, human-readable and editable serialisation scheme, under version control and configuration management, usable for tasks, requirements and other items of engineering documentation will (does) make it easier to build the level of comprehensive scripting and automation that (I believe) is required for a truly disciplined engineering process.

sigh, I miss the IDE days... you can say whatever you want about eclipse or svn, but... in those day I have a source tracker, a bug tracker, unit tests, a wiki internal doc all linked from eclipse; I got bug #ids, clicked on them, make my fix, test them, commit, etc... without miss the dots (in the commit message there was an autogenerated link to the bug, etc)
Yeah ... I'm sure all of this is available from Eclipse. But, like I said, its' an experiment for my own enjoyment and education. In a commercial environment, the best solution (by far) would be to use an off-the-shelf solution.
Do what I do and stick the markdown into yaml directly.
Fossil is a great, simple system. It's especially good with Windows because (imo) it integrates much better than the others since it's just a single binary you can put in your $PATH. Git especially seems so hacky.
By the way, does anyone know of a SCM written in Go? It seems that the feature list of Fossil would fit Go pretty well, the networking/local web UI stuff for example, self-contained binary as well.
They should all be written in ANSI C. C90, specifically.
I appreciate the motivation behind this ideology, but giving up 26 years of advancement in programming languages (not to mention security and safety) for compatibility with a vanishingly small number of operating systems (few, if any, of which are in use as development machines) is not worth it for tools like these.
I was introduced to Fossil through a previous HN post and I love it. For smaller personal projects, it's the best. I like that I can just put the repo file into Dropbox and then have my project's tickets, documentation, and code all in one place.

And from someone who doesn't write much C, I will say that the source is very easy to read and poke around in. Just a great project all around.

I use Fossil for personal, private projects. I've never used it with other people. But being able to replicate the wiki, issues etc and version them is very cool.

I use fossil to keep track of my code and use the wiki of a project as a scratchpad, design document, and general notes. I love it.

It can be self-hosted using a super-simple CGI script:

    #!/usr/bin/fossil
    repository: /path/to/project/repository.fossil
- which allows you to both clone over HTTP/HTTPS and access the Wiki and issue tracker via your browser. It has pretty decent access control and can allow you to configure a set of wiki pages to make read-only accessible to everyone, even when not logged in, to use as a project landing page for visitors.

You can also customize the CSS of a project, which is also versioned in the single sqlite db backing a repository.

Fossil is neat and the idea of a tickets tracker and wiki within the repo is very productive.

However I got spoiled by the power of Git. So what I do now is to keep a TiddlyWiki[1] on the Git repo, so I have the best of both worlds.

[1] http://tiddlywiki.com/

While I am a fan of chains of small cooperating tools, there is something to be said for a single large tool with a well-integrated feature set.

Here are some of the advantages you get when the code repo, bug tracker, and wiki are all part of the same coherent system:

1. When a checkin fixes a bug noted in the ticket tracker, you can reference it in the checkin comment with a subset of the ticket ID: "Fixes [3b52b91fc]" That ticket ID becomes clickable in the web view of the timeline, taking you directly to the referenced ticket. Yes, I know, this is not a unique feature, but the other systems that have this also integrate the ticket tracker and code repo. The point is that you get this feature out of the box with Fossil, for free.

2. Your next step is to close the bug ticket. This modifies the appearance of the checkin comment you created in the previous step in the Fossil UI timeline view, rendering the ticket ID as strikethrough text, so you can see it refers to a closed ticket without clicking on it. The key point here is that the integration is bidirectional.

(It would be even neater if Fossil would recognize the pattern "Fixes [artifact-ID]" in checkin comments and automatically close the ticket for you. It shouldn't be too difficult to add, since it's a unified system.)

3. Anywhere that Fossil accepts regular URLs, it will also accept artifact IDs. So, you can refer to checkins or tickets from the wiki, or from within a Markdown document checked into the code repo.

4. Because Fossil understands Markdown as one of its available wiki article formats, it can render Markdown documents in the code repo inside the Fossil UI when you click on them from the Files tab in the web UI.

5. That feature extends to other document types, too. This leads to the embedded documentation feature (http://fossil-scm.org/xfer/doc/trunk/www/embeddeddoc.wiki) which is a versioned alternative to the wiki. You use the wiki for articles that apply to all versions of the repository, or at least to the current trunk version. Where you instead need a given doc article to roll back to its historical content when you roll back the code, you want to use embedded documentation instead. You can use the wiki and embedded docs interchangeably, linking from one to the other, as needed.

I'm a long time git, hg and svn user who has been using fossil every day for over a year now and find it to be reliable, quick and easy to use. It is also very hackable and I've customized the "fossil ui" to my liking.

However, fossil does lacks some important features that svn, hg and git have:

* Fossil does not support versioning directories. In fossil only files are first class objects. It is not possible to commit an empty directory. This is a big shortcoming that all other major SCMs address.

* Cannot perform a "fossil diff" for just a directory and its descendants - i.e., no fossil equivalent of the following:

    # produce a diff for this directory and its descendants
    git diff .
* A "fossil merge" between distributed repos it will give commit attribution to the wrong user for all files in the merge - changes will be recorded as being made by the user performing the merge. This is particularly annoying because it makes "fossil blame" on a given file less effective when pinpointing who introduced what change.

There are other fossil issues, but those are the biggest ones that come to mind.

> Fossil does not support versioning directories. In fossil only files are first class objects. It is not possible to commit an empty directory. This is a big shortcoming that all other major SCMs address.

Hm? Neither git nor hg allow this either. The usual workaround in both is to put an placeholder file in the desired "empty" directory, such as a .gitignore.

hg and svn support versioning directories. I assumed that git also did. If it does not, I stand corrected.
You're also correct about hg not versioning empty directories with the default mercurial install. A previous place I worked had a non-standard extension - that unknown to me may very well have used the .keep file trick you described.

So it would appear that fossil not supporting versioning of directories puts it in good SCM company.

> Fossil does not support versioning directories.

While that is true, what would revision 2 look like? "This new directory is also empty, but more so?" My point is that an empty directory isn't really "versionable," in the sense that there is something there to be diffed.

I converted a few Subversion repos to Fossil, and the empty directories I'd stored were all easily replaced by a dependency in the build system, so that it was created at the point of need. In that sense, the directory is versioned as part of the Makefile.

In many cases, your existing tooling already takes care of this, as with "bin\Debug" and such in Visual Studio.

> Cannot perform a "fossil diff" for just a directory and its descendants

Yes, that would occasionally be nice.

Fossil does support directory names in checkins, though, so if you're certain the changes are all confined to one subtree, you can just check that change in, then diff what's left.

You can also "stash" a directory, then either diff the stash against the working checkout, or diff what's left, as your workflow requires.

> A "fossil merge" between distributed repos it will give commit attribution to the wrong user

I suspect that's because the full user table isn't included as part of a clone, nor are local user changes pushed back to the repo you cloned from.

The idea of federating identity management gives me the heebie-jeebies. Just ask the PGP folk how well that works.

If repo A clones from B, which clones from C, and you want changes made to A to be properly credited in C, the owners of A need to acquire a login on C, sync themselves to C instead of your B repo, and then check their changes in directly, bypassing B.

> Cannot perform a "fossil diff" for just a directory and its descendants

Thanks for the suggestion. I just checked in an enhancements so that this works now. https://www.fossil-scm.org/fossil/info/c46f98055cf49687

As for your other short-comings, please mention them on the fossil-users@lists.fossil-scm.org mailing list