I don't mean this personally, but I'm getting a bit tired of git users pointing to the reflog as protection against data loss. The reflog does serve as a way to access no-longer-extent commits--until those reflog entries expire, at which point they are garbage collected and no longer exist anywhere, period. By default, this expiration time is two weeks.
Yes, the reflog can help recover from certain classes of errors, but its band-aid over git's emphasis on destructive history rewriting is incomplete, and can, and does, crack in real-world cases.
The correct solution, I think--which none of the distributed version systems implement--is to provide a way to group related changesets into an übercommit. This übercommit may still be sliced and diced back down to the buggy micro-commits that detail its dirty development, but, by default, will be presented as a single monolithic changeset to the user. No history is lost, and none is rewritten; you're simply altering its presentation.
"I don't mean this personally, but I'm getting a bit tired of git users pointing to the reflog as protection against data loss.... By default, this expiration time is two weeks."
So, set it to ten years, and lose nothing of interest. (It's not a Y2K-like problem because the value of a commit decays over time. Nobody will need to go back in time ten years to recover a commit that wasn't in the main line, because nobody will even know enough to ask a question that could be an answer to.) Does that answer your objection?
"This übercommit may still be sliced and diced back down to the buggy micro-commits that detail its dirty development, but, by default, will be presented as a single monolithic changeset to the user. No history is lost, and none is rewritten; you're simply altering its presentation."
You could do that with git now. Branch for every commit, and squash it back down onto the main branch. Tag the final HEAD of the branch and include the tag in your squash commit record, and you can use it to recover all the component commits. If it bothers you that git still won't understand what that means, you're just a couple of shell scripts away from having the functionality fairly well supported.
(git, thanks to its heritage, shell scripts fairly well, and of course anything else that can do "shell-script-like" things (Python, perl, etc.) can handle it too. We have several simple scripts that sit on top of git and help us impose policy on our branch management. So, I'm not terribly sympathetic to criticisms of git that are one config change or a quick shell script away from being fixed. Although, probably not for the reason you think; it's not because I think those who don't customize their VCS is automatically a lazy developer, it's because everybody has their own unique needs.)
> So, set it to ten years, and lose nothing of interest... Does that answer your objection?
No. It's still lossy. To turn the question around: if Subversion expired changesets after a given length of time, I think you would complain. Likewise, if git expired mainline commits after a certain length of time, you would also complain (I sure hope). git is lossy, and I happen to think that's entirely the wrong thing for a VCS to be. Making it "less" lossy is kind of like trying to keep your teenage daughter "less" pregnant.
> You could do that with git now. [Lengthy explanation follows]
I can also do that right now in Mercurial using the group extension (http://www.selenic.com/mercurial/wiki/index.cgi/GroupExtensi...), which is possible because Mercurial, being written in Python, is trivial to extend. But that's not the same as being part of the Mercurial workflow, any more than the bookmark extension in Mercurial prior to hg 1.1 counted as a real answer to git topic branches, or Loom counts as bzr's answer to Mercurial's mq now: it's not part of the VCS. Yes, I can make these all work however I wish--but as much as people have now forgotten, it's also relatively easy to make CVS and Subversion work in similar ways through tools such as Quilt (http://savannah.nongnu.org/projects/quilt), which allow for rebasing, offline commits, and many other features that you think of as git/hg/bzr-specific. We've abandoned those tools for good reasons: they required extensions, shell scripts, and odd workflows to work in distributed environments. We will do the same to our existing VCSes unless they can approach a more ideal workflow.
Yes, the reflog can help recover from certain classes of errors, but its band-aid over git's emphasis on destructive history rewriting is incomplete, and can, and does, crack in real-world cases.
The correct solution, I think--which none of the distributed version systems implement--is to provide a way to group related changesets into an übercommit. This übercommit may still be sliced and diced back down to the buggy micro-commits that detail its dirty development, but, by default, will be presented as a single monolithic changeset to the user. No history is lost, and none is rewritten; you're simply altering its presentation.