I may be _entirely_ off base here.
(personally I find git's command line to be fantastic, but I often feel like I'm the only one.)
Mutating history is front and center in the changeset evolution framework people have been working on for some years now. The first step is that Mercurial tracks when it's safe to rebase or edit a commit: each commit has a "phase" which is "draft" initially, but changes to "public" when you push the commit somewhere. The history editing tools ('hg rebase', 'hg histedit', 'hg commit --amend') will then tell you when it's unsafe to edit a commit.
Really, it would be best if there was some way to retain the original commits while rebasing to clean the history. Time for a new DVCS?
When you rebase, commits are not lost. If there is a ref pointing at them then they will continue to stick around. If there isn't then the next time that gc is run they would be removed.
The solution to what you are looking for is to precede each rebase with a command to 'anchor' the current commit under a custom ref. If you wanted to look back in time, you'd use a corresponding command. This is all, say, 20 lines of shell, primarily using the git plumbing..
Of course this is just recreating a permanent reflog-work-alike, reflog of course already having this usecase covered for individual devs working on their machines...
If it is the other usecase of rebasing, rebasing public code, say on a centralized repo or the repo of your build fleet, that has you concerned, then instead of just set a policy of only permitting fast-forward commits in those cases. That is a reasonable thing to do, it is a legitimate workflow that git supports. There is no reason that you cannot keep auditable logs of exactly what has been going on with your git repo.
I think people hear "rewrites history" and let their imaginations run wild with sci-fi tales of wonder, only then to think of the grave horrors such power would enable... but forget to look at what actually is happening when you "rewrite history" in git. There is no reason to fear it.
Yeah, I very much agree with this. Rewriting history is a tool, a very powerful tool. It's something you can use if you want to.
It reminds me a little of a discussion I had recently with a developer who mostly used statically typed languages. I'm using to dynamically typed languages like Python and JavaScript, so it was puzzling for me to hear him talk about the horrors of dynamic types. He said things like "I pass a Person object to a function and the function might do anything with it -- like adding new methods and fields to it!". Yes, it is true that you can add a new method to an object in most dynamically typed languages. No, adding methods and fields by accident is not really a problem in real life.
Just because you have the option of doing something, doesn't mean that you must do it.
My git workflow is probably replicable in Mercurial, but git does it by default.
Bookmarks stay local by default, but they can be exported to the server if you like. There's nothing to enable any longer since it's a core feature.
I don't think you need to install those extensions, you just enable them by putting a line in .hgrc
This of them as major modes for Emacs, if you're familiar with that. Emacs comes with syntax highlighting support for a lot of languages and the mode is turned on automatically. Sometimes you need to install a new major mode yourself, but the bundled modes get you a long way.
In both cases the answer is pretty much nothing.
Git is not optimized for the minority case, it is optimized for simple implementation. It basically leaks implementation details left and right. I believe git users come to like this, because the core model is so simple (for a computer scientist). Git internally is just snapshots of the code connected with prev-version edges forming a directed acyclic graph and then some named pointers into this DAG.
I don't know which it better, but at least different: git has automatic garbage collection for dangling commits (after 30 days or so by default).
With Mercurial, if you want to remove dangling commits, you have to do it by hand. And if they have been pushed, you have to go to the remote repo and manually remove them there too. And everyone else who has pulled them, will need to manually remove them.
I've been able to successfully replicate all the Git use cases I can think of in Mercurial even if I think they are bad practices. Conversely, nothing I do makes git's cli anywhere near as good as hg. For me, that is the single biggest glaring problem with Git. I spend a very small minority of my time handling complicated history/branch issues as part of my major workflow and I spend an inordinate amount of time working with the interface to my source control. Git seems optimized for the minority case.