Se você empurrar um commit para o servidor, e depois reescrever que cometem localmente (com git reset, git rebase, git filter-branchou qualquer outra manipulação história) e, em seguida, empurrou o reescrito cometer volta para o servidor, você vai estragar qualquer outra pessoa que tinha puxado. Aqui está um exemplo; digamos que você tenha confirmado A e enviado para o servidor.
- * - * - A <- mestre
- * - * - A <- origem / mestre
Agora você decide reescrever A, da maneira que você mencionou, redefinindo e confirmando. Observe que isso deixa um commit pendente, A, que eventualmente será coletado como lixo, pois não está acessível.
-*-*-UMA
\
A '<- mestre
- * - * - A <- origem / mestre
Se outra pessoa, digamos Fred, puxar para baixo masterdo servidor enquanto você estiver fazendo isso, eles terão uma referência a A, a partir da qual eles podem começar a trabalhar:
- * - * - A '<- mestre
- * - * - A <- origem / mestre
- * - * - AB <- fred / master
Agora, se você pudesse empurrar seu A 'para origin / master, o que criaria um avanço não rápido, ele não teria A em seu histórico. Então, se Fred tentasse puxar novamente, ele de repente teria que fundir e reintroduziria o commit A:
- * - * - A '<- mestre
- * - * - A <- origem / mestre
- * - * - AB- \
\ * <- fred / master
UMA'--/
Se Fred perceber isso, ele poderia fazer um rebase, o que evitaria que o commit A reaparecesse. Mas ele teria que perceber isso e se lembrar de fazer isso; e se você tiver mais de uma pessoa que puxou A para baixo, todos eles teriam que rebase para evitar o commit extra de A na árvore.
Portanto, geralmente não é uma boa ideia alterar o histórico em um repo que outras pessoas usam. Se, no entanto, você souber que ninguém mais está puxando desse repo (por exemplo, é o seu próprio repo privado ou você só tem um outro desenvolvedor trabalhando no projeto com quem você pode coordenar facilmente), então você pode forçar atualizar executando:
git push -f
ou
git push origin +master
Ambos irão ignorar a verificação de um push não acelerado e atualizar o que está no servidor para sua nova revisão A ', abandonando a revisão A para que eventualmente seja coletada como lixo.
É possível que os push push sejam totalmente desativados com a receive.denyNonFastForwardsopção config. Esta opção é habilitada por padrão em repositórios compartilhados. Nesse caso, se você realmente quiser forçar um push, a melhor opção é excluir o branch e recriá-lo com git push origin :master; git push origin master:master. No entanto, a denyNonFastForwardsopção está habilitada por um motivo, que é descrito acima; em um repositório compartilhado, isso significa que agora todos os que o usam precisam garantir que eles sejam realocados no novo histórico.
Em um repositório compartilhado, geralmente é melhor apenas enviar novos commits para corrigir qualquer problema que você tenha; você pode usar git revertpara gerar commits que irão desfazer as mudanças dos commits anteriores.