> Well, you can set the expiration period for the reflog

Much easier, you can turn off garbage collection (if you set the expiration time on the reflog, you have to make sure to set gc.reflogexpireunreachable, not just gc.reflogexpire). This is indeed what I do whenever I work with Git as the frontend (though not when I uses Git programmatically as basically a versioned DB backend). But that's not about me. I'm fully conversant in Git, up to and including having hacked Git repositories using dulwich. It's about users in general, all of whom have to deal with this.

Of course, this has its own problems, because lots of Git usage patterns have evolved around creating garbage and then throwing it away rather than having an explicit and safe delete operation that is rarely used (or at least to hide revisions rather than to delete them), and because it may not be possible on hosted repositories, such as on GitHub (Bitbucket allows you to prevent force pushes to master branches, GitHub doesn't [1]).

And even when you've made it safe, you still cannot have unnamed branches or multiple checkouts [2].

The more general problem is that Git's GC is not a user interface design decision. Git having a GC is ultimately a result of it being easier to hack together your own transactions without using an actual DB backend such as SQLite when you use (mostly) functional data structures with a GC. While this makes Git a fairly robust versioned database, these and other implementation decisions spilling over into user space is something that has plagued Git for a long time: for full proficiency with Git you need a fairly deep understanding of implementation details.

> Then again, in my experience, if you manage to remove data or alter data which should not be removed or altered, and don't pick up on that before after the reflog expiration period, then you have bigger problems.

This can easily happen on branches that see only intermittent changes or on personal repositories. Git was originally designed for being heavily distributed work, and it shows; it's relatively safe when commits are regularly mirrored to a network of contributors, not so much when they don't.

And, again, this is a problem that should not even exist. One of the primary tenets of source control management -- a major reason why we even have it -- is to protect developers against their mistakes. In particular, there are many cases where VCSs are being used by non-technical people (such as technical writers working on documentation) and they cannot be expected to have a deep technical understanding of the tools they are using. VCS tools must therefore be error-resistant.

[1] GitHub in many ways is still shockingly primitive, such as how it still doesn't support attaching files to issues. Referencing gists via URL is a sort-of workaround, but even that becomes painful with binary files. But that's another story.

[2] The reason for the latter is subtle, but basically boils down that the GC either needs to have global knowledge of all checkouts in order to trace checkout-local refs such as HEAD properly (which may be lost by a simple mv) or that multiple checkouts that use the same branch can get in a battle over who gets to point it to which commit (e.g., commit to master in two checkouts, and only one commit operation can "win", because master cannot point to two commits at once).