O git é uma excelente ferramenta no desenvolvimento de projetos, além de manter o registro de mudanças, ele permite também a mudança de coisas já feitas, os commits já feitos. Pode ter situações que se faz necessária a mudança, seja por WIP's ou TODO esquecidos em alguma mensagem de commit ou dentro de arquivos.
Existe duas formas de alterar commits, o --amend da qual vamos tratar primeiro, é mais objetivo ele altera o último commit feito no branch atual. Exemplo de um --amend:
Outra forma de fazer essas alterações é com o rebase, ele permiti fazer alterações em commits mais antigos, não só isso, mas em "lotes", sendo possível alterar mais de 1 commit no mesmo fluxo. Usando o parâmetro -i, ele entra em modo iterativo e permite o uso de prefixos já pré definidos, como pick, edit, rename, para dizer o que fazer com o commit. Em um exemplo, vou editar 2 commits de um repositório (GNU Stow ), em um deles vou adicionar uma mudança nos arquivos e acrescentar mais informações na mensagem commit (com --amend, enquanto estou fazendo o rebase) e o outro vou apenas alterar a mensagem de commit. Para essas duas mudanças vou usar edit (que atualiza o commit para permitir acrescentar também uma mudança de arquivo, além de permitir alterar a mensagem de commit) e o reword (que atualiza apenas a mensagem).
Porém fazer essas mudanças tem um custo, por exemplo o de na hora de mandar as alterações para o repositório o git não deixar sem que você deixe explicito isso ao enviar, com o parâmetro --force (ex.: git push --force). Ele faz isso, pois as árvores entre seu repositório local e o remoto estão diferentes¹ no que se refere aos commits passados.