I'm not an emacs developer but I'd like to jump in:
As you may know, in git, when a commit is made it consists of these things:
- A complete of snapshot of the file structure of the entire repository and all file contents
- The commit message, commit time + author time, commiting person
- The SHA1 identifier of the previous commit(s) (there can be multiple in case of a merge commit)
All of these things enter into the SHA1 identifier of the commit! git has the tools to change any of the above a posteriori, but it's vital to understand that any such modification, even if it's just a typo in the commit message will modify the SHA1 of the commit. The old commit with it's identifier still exists, but it's 'dangling' i.e. it's typically not part of the local branch you are working in any more.
Any references to the old identifier of the commit become invalid at that point!
As long as any such discarded commit was not pushed to a public repository, it's generally considered fine to do these modifications to your liking.
However, once a commit is pushed out to a public place the situation changes. People may be using the old ID to refer to that specific commit, whether you know it or not.
Then, whether you want to allow 'rewriting history' depends entirely on the conventions in your project - there's no general rule. In emacs you may say it's OK, even recommened, to modify the staging branch a posteriori in case a mistake was made. Therefore, it's in general impossible to do the right thing without knowing the project policy.
In case rewriting history is not possible or wanted, git revert is there to help you: It simply creates a new commit which applies the reverse patch with an appropriate commit messate, that's all.
I urge you to read these:- http://git-scm.com/book/en/v2/Git-Internals-Git-References
- man git rebase (section "RECOVERING FROM UPSTREAM REBASE")
- man git tag (section "DISCUSSION - On Re-tagging")