I'm not familiar with other DCVS tools, but I have delved pretty heavily into the history rewriting capabilities of git. Git is just a power tool. It won't ruin your day like rm -rf will, but it will give you enough rope to rappel your way down into ontological horror.
I have been using it to write extended tutorials on my local system. I may find a bug at step 45 that needs to be fixed back at step 2. I am pretty sure that git was never designed for me to do this, but it can be done pretty safely, in a way that I can recover from.
Now, is this method of going back and fixing things in the past a good idea for general software development? Absolutely not! If I wrote a bug in march, it serves the team rather poorly to go back and replace every commit in the master branch with a new one that doesn't have the bug. And that's why I feel it's accurate to call it rewriting - sure, git keeps enough data around for you to recover from any boneheaded edit you may make to a branch, but from the perspective of a teammate you're still going back and modifying history. It's still confusing. You're still creating new commits out of their commits that have the same name, but different contents.
You're not looking at the possibility that someone may do a bunch of
development locally, then use rebase to clean it (the local changes)
up before pushing it out to a central repository (or merging it into
master). If you're really paranoid that someone will use rebase to screw up master, you can use a tool like gitosis or gitolite to manage permissions on a central repository. You can say that no one has permissions to push things to master that are not fast-forwards.
Scenario #1:
I'm working on a feature branch. I have a number of discrete changes
that I'm making. I attempt to keep each of these changes in its own
separate commit. After completing 10 such changes, I realize that I
introduced a bug in change 3. I commit the bugfix with the same
commit message title as change 3, but with a "squash!" prefixed at
the front of it. Now when I'm finished with my changes on the
feature branch I can run "git rebase -i". git-rebase will
automatically position the bugfix to change 3 next to change 3 and
set it up to be squashed into the change 3 commit. Then when I merge
my changes into master there are only commits for changes 1-12,
instead of 50 commits covering all of the minor bugs that I fixed
with my undeployed code.
Scenario #2:
Rewriting commit messages. This is one that I use all of the time at
work. I use a commit message template that has "Reviewed-by: ???" at
the bottom. When I do all of be topic branch development, I don't
get someone to review each individual commit prior to commiting it
(as that would defeat the purpose of a DVCS... might as well go back
to SVN at that point and managing chunks of changes prior to commits
with something like `quilt`). So now all of my commit messages have
"Reviewed-by: ???" on them. Prior to merging the changes back into
master, I can use git-rebase or git-filter-branch to go back and
edit my history to change "Reviewed-by: ???" to "Reviewed-by: Bob"
on my commit messages.
Often when pairing we'd commit with messages like "WIP: 1" "WIP: 2" etc. push pull switch machines (remote pairing) get checkpoints in there. Then before pushing to the main branch we'd roll all that up into one commit with a very helpful message. Boom solves a great workflow problem.
I have been using it to write extended tutorials on my local system. I may find a bug at step 45 that needs to be fixed back at step 2. I am pretty sure that git was never designed for me to do this, but it can be done pretty safely, in a way that I can recover from.
Now, is this method of going back and fixing things in the past a good idea for general software development? Absolutely not! If I wrote a bug in march, it serves the team rather poorly to go back and replace every commit in the master branch with a new one that doesn't have the bug. And that's why I feel it's accurate to call it rewriting - sure, git keeps enough data around for you to recover from any boneheaded edit you may make to a branch, but from the perspective of a teammate you're still going back and modifying history. It's still confusing. You're still creating new commits out of their commits that have the same name, but different contents.