Git não-avanço rápido rejeitado

Eu sinto que esta pergunta foi feita muitas vezes, mas a solução é tipicamente “eu deletei o diretório e refiz meu trabalho com um novo checkout”. Eu fiz um commit e push, mas percebi que me referi ao número do ticket errado na mensagem de commit. Então eu olhei no SO para uma solução rápida e acabei digitando o seguinte no terminal:

$ git reset --soft HEAD^ $ git commit -m "... correct message ..." 

O único problema é que estou recebendo a seguinte mensagem de erro:

 To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes before pushing again. See the 'Note about fast-forwards' section of 'git push --help' for details. 

Eu estou usando o modelo git-flow e estou trabalhando no ramo de desenvolvimento. Como eu posso mesclar as coisas de volta para fazer feliz de novo?

Força git push :

 git push origin +develop 

Se você enviar um commit para o servidor, e então rewrite o commit localmente (com git reset , git rebase , git filter-branch , ou qualquer outra manipulação do histórico), e então empurrar o commit reescrito de volta para o servidor, você irá apertar qualquer outro que tivesse puxado. Aqui está um exemplo; digamos que você tenha confirmado A e o tenha enviado para o servidor.

 - * - * - A <- mestre

 - * - * - A <- origem / mestre

Agora você decide rewrite A, da maneira que você mencionou, redefinindo e reconfigurando. Observe que isso deixa um commit pendente, A, que eventualmente será coletado como não acessível.

 -*-*-UMA
     \
      Um '<- mestre

 - * - * - A <- origem / mestre

Se outra pessoa, digamos Fred, puxar o master do servidor enquanto você estiver fazendo isso, ele terá uma referência a A, da qual ele pode começar a trabalhar:

 - * - * - A '<- mestre

 - * - * - A <- origem / mestre

 - * - * - AB <- fred / master

Agora, se você fosse capaz de empurrar seu A 'para origem / master, o que criaria um não avanço rápido, ele não teria A em sua história. Então, se Fred tentasse puxar novamente, de repente ele teria que se fundir e reintroduzir o commit de A:

 - * - * - A '<- mestre

 - * - * - A <- origem / mestre

 - * - * - AB- \ 
     \ * <- fred / master
      UMA'--/

Se Fred perceber isso, ele pode fazer um rebase, o que evitaria que o commit A reaparecesse novamente. Mas ele teria que perceber isso e lembrar de fazer isso; e se você tiver mais de uma pessoa que puxou A para baixo, todos eles teriam que fazer o rebase para evitar o commit A adicional na tree.

Então, geralmente não é uma boa ideia mudar o histórico em um repository que outras pessoas usam. Se, no entanto, você souber que ninguém está tirando esse repo (por exemplo, é o seu próprio repository privado, ou você tem apenas 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 ignorarão a verificação de um push não-avanço rápido e atualizarão o que está no servidor para a nova revisão A ', abandonando a revisão A para que ela acabe sendo coletada como lixo.

É possível que os push forçados sejam totalmente desativados com a opção de configuração receive.denyNonFastForwards . Esta opção é ativada por padrão em repositorys 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 git push origin :master; git push origin master:master . No entanto, a opção denyNonFastForwards é ativada por um motivo, descrito acima; em um repository compartilhado, isso significa que agora todos que o usam precisam garantir o novo armazenamento para o novo histórico.

Em um repository compartilhado, geralmente é melhor apenas enviar novos commits para corrigir qualquer problema que você tenha; você pode usar o git revert para gerar commits que irão desfazer as mudanças dos commits anteriores.

Você pode ter que fazer um git pull , que pode auto fundir coisas para você. Então você pode confirmar novamente. Se você tiver conflitos, ele solicitará que você os resolva.

Lembre-se, você tem que especificar qual o ramo a ser puxado se você ainda não atualizou seu gitconfig para especificar …

Por exemplo:

 git pull origin develop:develop 

Eu estava usando o EGit e enfrentei esse problema também. Apenas tentei rebase o ramo atual e funcionou.