Como forçar um push a redefinir para o repositório remoto?

94

Nosso branch master remoto de alguma forma ficou confuso. O código de desenvolvimento atual está no branch master junto com os commits mais recentes. Obviamente, o código de desenvolvimento não está pronto para o branch master.

Então, em meu repositório local, fiz uma redefinição para a tag mais recente git reset --hard (Tag),. O branch master agora está correto no meu repositório local. Agora, quando tento enviar as alterações para o repositório remoto git push origin master, recebo um erro:

To (REMOTE GIT REPOSITORY LOCATION)
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

Então, depois de dar uma olhada, descobri a --forceopção. Então, forcei um push no repositório remoto git push --force origin master, e ainda recebo um erro:

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To (REMOTE GIT REPOSITORY LOCATION)
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'

Não consigo fazer pull no master, porque contém código de desenvolvimento que não pode estar no master.

Samwell
fonte
3
Acho que a mensagem significa que você não tem o direito de fazer um push não rápido.
svick
3
Você estava certo, obrigado. No arquivo de configuração do repositório remoto denyNonFastforwards = true,. Mudei para falso, empurrei minhas alterações e depois mudei de volta para verdadeiro. Obrigado novamente a todos, pela ajuda.
samwell
2
@samwell, marque a resposta de svick como aceita
hultqvist
@samwell a resposta de svick funcionou para você ou não?
Songo,
Para aqueles que precisam de detalhes sobre como desativar denyNonFastForwards como o samwell fez, mais instruções podem ser encontradas aqui: stackoverflow.com/a/43721579/2073804
ron190

Respostas:

152

A mensagem significa que você não tem permissão para fazer push não acelerado.

Seu repositório remoto provavelmente está denyNonFastforwards = trueem sua configuração. Se você mudar isso, git push --forcedeve funcionar.

Para alterar a configuração, você precisa acessar a máquina com o repositório remoto. A partir daí, faça git config receive.denynonfastforwards false.

svick
fonte
1
Você pode fazer um git configpara um servidor? Ou talvez você estivesse usando isso metaforicamente. Para brincar com essas idéias, criei um repositório de teste em /opt/git(meu espaço do servidor git) e, em seguida, modifiquei essa configuração em /opt/git/the_repo/the_repo.git/config. Mas uma vez feito o git push --force origin SHA:branchtrabalho conforme necessário.
HankCa
4
A mensagem de erro terá uma linha que começa com "erro: falha ao enviar alguns refs para <seu repositório>" onde <seu repositório> é o caminho que termina em .git, que é um diretório que contém um arquivo chamado "config". Este arquivo "config" é onde você pode definir denyNonFastforwards = false
emery
1
O comentário de @emery é valioso. Às vezes, a pasta no servidor terá sua origem configurada para algo como /srv/git/repo.git. Esta é a configuração que tem denyNonFastForwards definido, não a pasta do aplicativo.
Elijah Lynn de
1
@hsalimi Se você não tiver acesso ao servidor, entre em contato com o administrador do servidor e faça com que ele o desligue temporariamente para que possa forçar o push e, em seguida, ligue-o novamente. É improvável que a maioria esteja em posição de fazer isso. Pode ser mais comum em um ambiente interno com sua própria equipe de hospedagem.
Elijah Lynn de
1
Isso é inicialmente frustrante, mas a beleza disso é: o controle remoto é totalmente protegido por padrão e, se você, como desenvolvedor, estiver fazendo rebases intencionalmente e corretamente, poderá substituir essa configuração para permitir o comportamento perigoso. Rebasing é algo que todo usuário git deve saber como fazer - e quando não fazer. doc1 doc2
moodboom
15

O controle remoto não permite avanços não rápidos.

Sua melhor opção é fazer git reverttodos os commits que não deveriam estar lá e ter mais cuidado no futuro.

git revert [commit]irá criar um novo commit que desfaz tudo [commit]o que fez.

richo
fonte
Algumas configurações no repositório remoto bloquearam todas as alterações não aceleradas.
samwell
Se você fizer isso e precisar reaplicar os commits, o histórico não será removido em uma reversão, apenas as alterações do código, e você não será capaz de escolher os commits ou mesclar
mtpultz
12

Etapas para habilitar permanentemente force push no seguinte estilo

git push -f myrepo my-branch

Edite o arquivo chamado "config" na pasta que termina em ".git" em seu repositório remoto

Na saída de linha de comando do git do push com falha, procure a linha que diz algo como:

error: failed to push some refs to 'ssh://[email protected]/srv/git/myrepo.git

então

ssh [email protected]
cd /srv/git/myrepo.git
vi config

Defina "denyNonFastforwards" como falso

Em "config", defina

[receive]
        denyNonFastforwards = false

Agora você pode enviar a partir de sua máquina local com -f

git push -f myrepo my-branch
esmeril
fonte
Como fazer isso sem acesso ao SSH para o repositório git nua?
Vladimir Vukanac
Talvez use o comando git revert como sugere richo? Se você fizer backup do estado atual do repo primeiro, ainda poderá mesclar seu código para avançar.
esmeril de
git reverté meio complicado quando você tem mesclagens. Para ser mais complicado, meu caso tem 3 merge, dos quais um está com muito antigo ~ 20 commit divergente do desenvolvimento, o segundo é meio que merge do master - feio pra caralho.
Vladimir Vukanac
1
Talvez a solução seja redefinir para o estado desejado, fazer backup (stash), puxar novamente e aplicar o backup (stash).
Vladimir Vukanac
1
mrW você ainda pode mesclar a base de código que deseja em cima de uma base de código revertida / retirada
esmeril de
11

Tente usar o -fsinalizador e colocá-lo após o nome do branch remoto.

git push origin master -f

Chris Ledet
fonte
1
Não, isso também não funcionou. Eu também tentei git push -f origin mastere mesmo resultado. Nas duas vezes que tentei, recebi a segunda versão da mensagem de erro.
samwell
2

Você não tem permissão para fazer git push que não seja um avanço rápido.

  1. Se o remoto for o GitHub, vá até https://github.com/$USER/$REPO/settings/branchese cancele a proteção do branch em questão.

    insira a descrição da imagem aqui

    Você precisa ser administrador do repo para fazer isso.

  2. Se o remoto for seu próprio servidor git, execute git config receive.denynonfastforwards false-o.

filiph
fonte
Esteja ciente de que para instâncias do Git Hub Enterprise, os envios para o branch padrão (geralmente "master") podem ser desabilitados no nível da instância. Isso significa que mesmo se "master" não estiver protegido, e mesmo se você for um administrador de site, não será capaz de forçar o envio para o branch padrão. Supondo que você tenha permissões, você pode contornar isso temporariamente mudando o branch padrão para outra coisa, fazendo seu force-push e depois voltando.
Christopher Hunter
2

A melhor maneira de contornar isso é excluir o branch remoto e reenviá-lo:

git push origin master --delete
git push origin master
Danilo Souza Morães
fonte
0

O problema ocorre porque a ramificação atual não está configurada corretamente para o PULL . Primeiro verifique se o branch upstream está configurado corretamente para o pull usando - git remote show origin. Você pode encontrá-lo na seção - agências locais configurados para 'git pull': . Caso contrário, configure-o usando:

git config branch.MYBRANCH.merge refs/heads/MYBRANCH

Dê o nome de filial apropriado para o marcador de posição - MYBRANCH

Sudheesh.MS
fonte
0

Estou usando este grupo de comandos para redefinir meu repo remoto, isso irá reinicializar seu repo local e vincular novamente com seu repo remoto, em seguida, forçar o envio das atualizações.

Acho que essa maneira não vai funcionar no seu caso, mas pode ser útil para outra pessoa

vá para a pasta de origem e execute os comandos: observe que https://github.com/*.gité o seu link de repo remoto

git init
git remote add origin https://github.com/*.git
git add .
git commit -m "initial commit"
git push origin master -f
git push --set-upstream origin master

**Note: this will clear all your git history on your master branch**

Khaled AbuShqear
fonte
0

Para mim, a dica de @svick apontou na direção certa. Como o servidor git que eu queria modificar é na verdade minha máquina, entrei nele e fiz um git config --global receive.denynonfastforwards falsepara alterar todos os repos para aceitar um push forçado não-ff. Não funcionou fora da caixa. O que descobri foi que na configuração lá já estava receive.denynonfastforwards=truedefinido e não podia ser apagado com git config --global --unset receive.denynonfastforwards. Fazer a edição no repo manualmente ( vi config) funcionou, no entanto.

jglathe
fonte
0

Resolvi removendo o branch master de protegido e também padrão, que é apenas sobre regras de branch protegido na configuração de um repositório.

dasra khadka
fonte