Eu tinha um repositório que tinha alguns commits ruins (D, E e F para este exemplo).
Mestre ABCDEF e origem / mestre
Eu modifiquei o repositório local especificamente com a git reset --hard
. Peguei uma ramificação antes da redefinição, agora tenho um repositório que se parece com:
A-B-C master
\ D-E-F old_master
A-B-C-D-E-F origin/master
Agora, eu precisava de algumas partes desses commits ruins, então selecionei os bits necessários e fiz alguns novos commits; agora, tenho o seguinte localmente:
A-B-C-G-H master
\ D-E-F old_master
Agora, quero levar esse estado de coisas ao repositório remoto. No entanto, quando tento fazer um git push
Git educadamente , não consigo :
$ git push origin +master:master --force
Total 0 (delta 0), reused 0 (delta 0)
error: denying non-fast forward refs/heads/master (you should pull first)
To [email protected]:myrepo.git
! [remote rejected] master -> master (non-fast forward)
error: failed to push some refs to '[email protected]:myrepo.git'
Como faço para que o repositório remoto assuma o estado atual do repositório local?
git push -force
mais cuidado .Respostas:
Se forçar um push não ajuda ("
git push --force origin
" ou "git push --force origin master
" deve ser suficiente), pode significar que o servidor remoto está recusando impulsos sem avanço rápido por meio da variável de configuração receive.denyNonFastForwards (consulte a página de manual do git config para obter descrição) ou via gancho de atualização / pré-recebimento.Com o Git mais antigo, você pode contornar essa restrição excluindo "
git push origin :master
" (consulte ':' antes do nome do ramo) e "git push origin master
" recriando o ramo específico.Se você não pode alterar isso, a única solução seria, em vez de reescrever o histórico, criar uma confirmação de alterações reversas no DEF :
fonte
get revert HEAD~N
ajudou.N
é o número de confirmações. Por exemplo, se eu precisar cometer o anterior, eu vou usargit revert HEAD~1
Para complementar a resposta de Jakub, se você tiver acesso ao servidor remoto do git no ssh, poderá acessar o diretório remoto do git e definir:
Em seguida, volte ao seu repositório local, tente novamente fazer o seu commit com
--force
:E, finalmente, reverta a configuração do servidor no estado protegido original:
fonte
vi
são fornecidos neste SO post: stackoverflow.com/a/43721579/2073804Em vez de consertar sua ramificação "principal", é muito mais fácil trocá-la por sua "mestre desejada" renomeando as ramificações. Consulte https://stackoverflow.com/a/2862606/2321594 . Dessa forma, você não deixaria nenhum vestígio de vários logs de reversão.
fonte
Todo o negócio de redefinição de tarefas parecia muito complicado para mim.
Então, eu fiz algo semelhante para obter minha pasta src no estado que eu tinha alguns commits atrás
Dessa forma, o estado de coisas no src é mantido em um arquivo tar e o git é forçado a aceitar esse estado sem muita preocupação, basicamente o diretório src é substituído pelo estado que ele tinha vários commits atrás.
fonte
Para os usuários do GitHub, isso funcionou para mim:
git reset --hard <full_hash_of_commit_to_reset_to>
git push --force
Isso "corrigirá" o histórico da ramificação em sua máquina local e no servidor GitHub, mas qualquer pessoa que sincronizou essa ramificação com o servidor desde a confirmação incorreta terá o histórico em sua máquina local. Se eles tiverem permissão para enviar diretamente para a ramificação, essas confirmações aparecerão imediatamente quando forem sincronizadas.
Tudo o que todo mundo precisa fazer é o
git reset
comando acima para "corrigir" a ramificação em sua máquina local. É claro que eles precisariam ter cuidado com quaisquer confirmações locais feitas neste ramo após o hash de destino. Escolha / faça backup da cereja e aplique novamente conforme necessário, mas se você estiver em uma ramificação protegida, o número de pessoas que podem se comprometer diretamente com ela provavelmente será limitado.fonte