Force o "git push" para substituir arquivos remotos
768
Quero enviar meus arquivos locais e tê-los em um repositório remoto, sem precisar lidar com conflitos de mesclagem. Eu só quero que minha versão local tenha prioridade sobre a remota.
Não está claro se você deseja substituir apenas os arquivos .git ou a cópia de trabalho associada. Se for o repositório git, git push é a resposta. Se você deseja atualizar a cópia de trabalho remoto, você tem que usar um post-receive gancho
Pierre-Olivier Vares
@ Mike que funciona para mim por alguma razão ... maravilha o que estava acontecendo com o OP
Uma causa provável: o push de força não funciona é que ele pode ter sido explicitamente desativado no repositório remoto (para garantir que nada seja perdido devido a contribuidores idiotas e / ou malignos): use config receive.denyNonFastforwardspara descobrir.
precisa
Respostas:
1088
Você deve poder forçar sua revisão local ao repositório remoto usando
git push -f <remote> <branch>
(por exemplo git push -f origin master). Sair <remote>e <branch>forçará o envio de todos os ramos locais que foram definidos --set-upstream.
Apenas esteja avisado, se outras pessoas estiverem compartilhando este repositório, o histórico de revisões entrará em conflito com o novo. E se eles tiverem confirmações locais após o ponto de mudança, elas se tornarão inválidas.
Atualização : Pensei em acrescentar uma nota lateral. Se você estiver criando alterações que outros revisarão, não é incomum criar uma ramificação com essas alterações e fazer uma nova reformulação periódica para mantê-las atualizadas com a ramificação principal de desenvolvimento. Deixe que outros desenvolvedores saibam que isso acontecerá periodicamente para que eles saibam o que esperar.
Atualização 2 : devido ao número crescente de espectadores, gostaria de adicionar algumas informações adicionais sobre o que fazer quando upstreamocorrer um impulso de força.
Digamos que eu tenha clonado seu repositório e adicionamos alguns commits dessa forma:
D ---- E tópico
/
Desenvolvimento A ---- B ---- C
Porém, mais tarde, o developmentramo é atingido com a rebase, o que fará com que eu receba um erro assim quando executar git pull:
Desempacotando objetos: 100% (3/3), pronto.
De <repo-location>
* desenvolvimento da filial -> FETCH_HEAD
Mesclagem automática de <files>
CONFLITO (conteúdo): Mesclar conflito em <locations>
Falha na mesclagem automática; conserte conflitos e depois confirme o resultado.
Aqui eu poderia resolver os conflitos e commit, mas isso me deixaria com uma história de submissão realmente feia:
C ---- D ---- E ---- F tópico
/ /
A ---- B -------------- C 'desenvolvimento
Pode parecer atraente de usar, git pull --forcemas tenha cuidado, pois isso deixará você com confirmações ociosas:
D ---- E tópico
A ---- B ---- C 'desenvolvimento
Então provavelmente a melhor opção é fazer a git pull --rebase. Isso exigirá que eu resolva conflitos como antes, mas para cada etapa, em vez de confirmar, eu usarei git rebase --continue. No final, o histórico de consolidação ficará muito melhor:
Tópico D '--- E'
/
A ---- B ---- C 'desenvolvimento
O envio forçado com uma "concessão" permite que o envio forçado falhe se houver novas confirmações no controle remoto que você não esperava (tecnicamente, se você ainda não as tiver buscado no ramo de rastreamento remoto), o que é útil se você não deseja substituir acidentalmente os commits de outra pessoa que você ainda não conhecia e apenas deseja substituir o seu:
git push <remote> <branch> --force-with-lease
Você pode aprender mais detalhes sobre como usar --force-with-leaselendo qualquer um dos seguintes:
Como esta é a resposta selecionada, vou comentar aqui. Usar força não é um problema ao trabalhar sozinho. Por exemplo, meu host na nuvem começa com seu próprio git. Se trabalho localmente e construo um projeto, e quero colocá-lo no meu host de nuvem (OpenShift), tenho dois projetos git separados. Meu local e meu OpenShift. Eu obtenho meu local exatamente como eu gosto, mas agora quero visualizá-lo no meu OpenShift. Você então pressiona para o OpenShift pela primeira vez, usando o -fsinalizador. Basicamente, colocando seu git local no OpenShift.
Wade
128
Você quer forçar push
O que você basicamente quer fazer é forçar o envio de sua filial local para substituir a remota.
Se você quiser uma explicação mais detalhada de cada um dos seguintes comandos, consulte a minha seção de detalhes abaixo. Você basicamente tem 4 opções diferentes para empurrar com força com o Git:
Se você quiser uma explicação mais detalhada de cada comando, consulte a minha seção de respostas longas abaixo.
Aviso: o empurrão forçado substituirá o ramo remoto pelo estado do ramo que você está empurrando. Certifique-se de que é isso que você realmente deseja fazer antes de usá-lo; caso contrário, poderá substituir as confirmações que realmente deseja manter.
Forçar empurrando detalhes
Especificando o controle remoto e a ramificação
Você pode especificar completamente ramificações específicas e um controle remoto. A -fbandeira é a versão curta do--force
Quando o ramo a ser enviado é omitido, o Git descobrirá isso com base nas suas configurações. Nas versões Git após a 2.0, um novo repositório terá configurações padrão para enviar por push a ramificação com check-out atualmente:
git push <remote> --force
enquanto antes da 2.0, novos repositórios terão configurações padrão para enviar várias ramificações locais. As configurações em questão são as configurações remote.<remote>.pushe push.default(veja abaixo).
Omitindo o controle remoto e a ramificação
Quando o controle remoto e o ramo são omitidos, o comportamento de just git push --forceé determinado pelas suas push.defaultdefinições de configuração do Git:
git push --force
A partir do Git 2.0, a configuração padrão, simplebasicamente enviará sua ramificação atual à sua contraparte remota upstream. O controle remoto é determinado pela branch.<remote>.remoteconfiguração da ramificação e, por padrão, o repositório de origem.
Antes do Git versão 2.0, a configuração padrão matchingbasicamente empurra todos os seus ramos locais para ramos com o mesmo nome no controle remoto (cujo padrão é origem).
Força forçando com mais segurança com --force-with-lease
O envio forçado com uma "concessão" permite que o envio forçado falhe se houver novas confirmações no controle remoto que você não esperava (tecnicamente, se você ainda não as tiver buscado no ramo de rastreamento remoto), o que é útil se você não deseja substituir acidentalmente os commits de outra pessoa que você ainda não conhecia e apenas deseja substituir o seu:
git push <remote> <branch> --force-with-lease
Você pode aprender mais detalhes sobre como usar --force-with-leaselendo qualquer um dos seguintes:
Você está certo, mas isso realmente só deve ser usado em situações excepcionais .
Scott Berrevoets
1
@ScottBerrevoets " Eu preferiria pressionar o que tenho e deixá-lo sobrescrever remotamente, em vez de integrar. " Dei ao OP exatamente o que ele pedia.
Eu sei, mas o OP pode não estar ciente das consequências de fazer isso. Você tecnicamente respondeu à pergunta, mas acho que um aviso para não fazer isso não está fora de lugar.
22814 Scott Berrevoets
1
@ScottBerrevoets Estou tentando ter um moderador mesclando minha resposta no canônico, porque mencionei a nova --force-with-leaseopção;)
Outra opção (para evitar qualquer pressão forçada que possa ser problemática para outros colaboradores) é:
coloque seus novos commits em um ramo dedicado
redefinir sua masteremorigin/master
mesclar seu ramo dedicado master, mantendo sempre as confirmações do ramo dedicado (ou seja, criar novas revisões sobre as masterquais espelhará seu ramo dedicado).
Veja " comando git para criar um ramo como outro " para estratégias para simular a git merge --strategy=theirs.
Dessa forma, você pode enviar master para controle remoto sem precisar forçar nada.
@alexkovelsky Qualquer envio forçado reescreveria o histórico, forçando outros usuários do repositório a redefinir seu próprio repositório local para corresponder aos confirmados enviados recentemente. Essa abordagem cria apenas novos commit e não requer um push forçado.
VonC
1
Eu sugiro que você adicionar um título para a sua resposta: "Você não quer empurrar força" :)
alexkovelsky
@alexkovelsky Good point. Eu editei a resposta de acordo.
VonC 16/01/19
4
O git push -f é um pouco destrutivo, pois redefine todas as alterações remotas que foram feitas por qualquer outra pessoa da equipe. Uma opção mais segura é {git push --force-with-lease}.
O que {--force-with-lease} faz é recusar-se a atualizar uma ramificação, a menos que seja o estado que esperamos; ou seja, ninguém atualizou o ramo a montante. Na prática, isso funciona verificando se o ref upstream é o que esperamos, porque refs são hashes e codificam implicitamente a cadeia de pais em seu valor. Você pode dizer ao {--force-with-lease} exatamente o que verificar, mas por padrão verificará a referência remota atual. O que isso significa na prática é que, quando Alice atualiza sua ramificação e a envia para o repositório remoto, a cabeça indicadora da ramificação é atualizada. Agora, a menos que Bob faça uma busca no controle remoto, sua referência local ao controle remoto estará desatualizada. Quando ele for empurrar usando {--force-with-lease}, o git verificará o árbitro local contra o novo controle remoto e se recusará a forçar o empurrão. {--force-with-lease} efetivamente apenas permite forçar push se mais ninguém tiver enviado alterações até o controle remoto nesse meio tempo. É {--force} com o cinto de segurança.
git push origin --force
funcionou para você?config receive.denyNonFastforwards
para descobrir.Respostas:
Você deve poder forçar sua revisão local ao repositório remoto usando
(por exemplo
git push -f origin master
). Sair<remote>
e<branch>
forçará o envio de todos os ramos locais que foram definidos--set-upstream
.Apenas esteja avisado, se outras pessoas estiverem compartilhando este repositório, o histórico de revisões entrará em conflito com o novo. E se eles tiverem confirmações locais após o ponto de mudança, elas se tornarão inválidas.
Atualização : Pensei em acrescentar uma nota lateral. Se você estiver criando alterações que outros revisarão, não é incomum criar uma ramificação com essas alterações e fazer uma nova reformulação periódica para mantê-las atualizadas com a ramificação principal de desenvolvimento. Deixe que outros desenvolvedores saibam que isso acontecerá periodicamente para que eles saibam o que esperar.
Atualização 2 : devido ao número crescente de espectadores, gostaria de adicionar algumas informações adicionais sobre o que fazer quando
upstream
ocorrer um impulso de força.Digamos que eu tenha clonado seu repositório e adicionamos alguns commits dessa forma:
Porém, mais tarde, o
development
ramo é atingido com arebase
, o que fará com que eu receba um erro assim quando executargit pull
:Aqui eu poderia resolver os conflitos e
commit
, mas isso me deixaria com uma história de submissão realmente feia:Pode parecer atraente de usar,
git pull --force
mas tenha cuidado, pois isso deixará você com confirmações ociosas:Então provavelmente a melhor opção é fazer a
git pull --rebase
. Isso exigirá que eu resolva conflitos como antes, mas para cada etapa, em vez de confirmar, eu usareigit rebase --continue
. No final, o histórico de consolidação ficará muito melhor:Atualização 3: Você também pode usar a
--force-with-lease
opção como um impulso de força "mais seguro", conforme mencionado por Cupcake em sua resposta :fonte
-f
sinalizador. Basicamente, colocando seu git local no OpenShift.Você quer forçar push
O que você basicamente quer fazer é forçar o envio de sua filial local para substituir a remota.
Se você quiser uma explicação mais detalhada de cada um dos seguintes comandos, consulte a minha seção de detalhes abaixo. Você basicamente tem 4 opções diferentes para empurrar com força com o Git:
Se você quiser uma explicação mais detalhada de cada comando, consulte a minha seção de respostas longas abaixo.
Aviso: o empurrão forçado substituirá o ramo remoto pelo estado do ramo que você está empurrando. Certifique-se de que é isso que você realmente deseja fazer antes de usá-lo; caso contrário, poderá substituir as confirmações que realmente deseja manter.
Forçar empurrando detalhes
Especificando o controle remoto e a ramificação
Você pode especificar completamente ramificações específicas e um controle remoto. A
-f
bandeira é a versão curta do--force
Omitindo o ramo
Quando o ramo a ser enviado é omitido, o Git descobrirá isso com base nas suas configurações. Nas versões Git após a 2.0, um novo repositório terá configurações padrão para enviar por push a ramificação com check-out atualmente:
enquanto antes da 2.0, novos repositórios terão configurações padrão para enviar várias ramificações locais. As configurações em questão são as configurações
remote.<remote>.push
epush.default
(veja abaixo).Omitindo o controle remoto e a ramificação
Quando o controle remoto e o ramo são omitidos, o comportamento de just
git push --force
é determinado pelas suaspush.default
definições de configuração do Git:A partir do Git 2.0, a configuração padrão,
simple
basicamente enviará sua ramificação atual à sua contraparte remota upstream. O controle remoto é determinado pelabranch.<remote>.remote
configuração da ramificação e, por padrão, o repositório de origem.Antes do Git versão 2.0, a configuração padrão
matching
basicamente empurra todos os seus ramos locais para ramos com o mesmo nome no controle remoto (cujo padrão é origem).Você pode ler mais
push.default
configurações lendogit help config
ou uma versão on-line da página de manual do git-config (1) .Força forçando com mais segurança com
--force-with-lease
O envio forçado com uma "concessão" permite que o envio forçado falhe se houver novas confirmações no controle remoto que você não esperava (tecnicamente, se você ainda não as tiver buscado no ramo de rastreamento remoto), o que é útil se você não deseja substituir acidentalmente os commits de outra pessoa que você ainda não conhecia e apenas deseja substituir o seu:
Você pode aprender mais detalhes sobre como usar
--force-with-lease
lendo qualquer um dos seguintes:git push
documentaçãofonte
--force-with-lease
opção;)
Outra opção (para evitar qualquer pressão forçada que possa ser problemática para outros colaboradores) é:
master
emorigin/master
master
, mantendo sempre as confirmações do ramo dedicado (ou seja, criar novas revisões sobre asmaster
quais espelhará seu ramo dedicado).Veja " comando git para criar um ramo como outro " para estratégias para simular a
git merge --strategy=theirs
.Dessa forma, você pode enviar master para controle remoto sem precisar forçar nada.
fonte
O git push -f é um pouco destrutivo, pois redefine todas as alterações remotas que foram feitas por qualquer outra pessoa da equipe. Uma opção mais segura é {git push --force-with-lease}.
O que {--force-with-lease} faz é recusar-se a atualizar uma ramificação, a menos que seja o estado que esperamos; ou seja, ninguém atualizou o ramo a montante. Na prática, isso funciona verificando se o ref upstream é o que esperamos, porque refs são hashes e codificam implicitamente a cadeia de pais em seu valor. Você pode dizer ao {--force-with-lease} exatamente o que verificar, mas por padrão verificará a referência remota atual. O que isso significa na prática é que, quando Alice atualiza sua ramificação e a envia para o repositório remoto, a cabeça indicadora da ramificação é atualizada. Agora, a menos que Bob faça uma busca no controle remoto, sua referência local ao controle remoto estará desatualizada. Quando ele for empurrar usando {--force-with-lease}, o git verificará o árbitro local contra o novo controle remoto e se recusará a forçar o empurrão. {--force-with-lease} efetivamente apenas permite forçar push se mais ninguém tiver enviado alterações até o controle remoto nesse meio tempo. É {--force} com o cinto de segurança.
fonte
Funciona para mim:
fonte
Etapas simples usando tortoisegit
GIT fornecendo arquivos locais confirmados e enviando para o repositório git.
Passos :
1) stash altera o nome do stash
2) puxar
3) esconderijo pop
4) confirmar 1 ou mais arquivos e fornecer autor e data do conjunto de descrição das alterações de confirmação
5) empurrar
fonte