Como forçar uma substituição de arquivos locais em um git pull
?
O cenário é o seguinte:
- Um membro da equipe está modificando os modelos para um site em que estamos trabalhando
- Eles estão adicionando algumas imagens ao diretório images (mas esquecem de adicioná-las sob controle de origem)
- Eles estão enviando as imagens por correio, mais tarde, para mim
- Estou adicionando as imagens sob o controle de origem e enviando-as para o GitHub junto com outras alterações
- Eles não podem receber atualizações do GitHub porque o Git não deseja substituir seus arquivos.
Este é o erro que estou recebendo:
erro: O arquivo da árvore de trabalho não rastreado 'public / images / icon.gif' seria substituído por mesclagem
Como forço o Git a substituí-los? A pessoa é designer - geralmente, eu resolvo todos os conflitos manualmente, para que o servidor tenha a versão mais recente que eles precisam atualizar no computador.
git reset --hard origin/branch_to_overwrite
git branch <branch> -D
2. Redefina para uma confirmação antes do conflito:git reset <commit> --hard
3. Recrie a ramificação:git branch <branch>
4. Defina o rastreamento para o servidor:git --set-upstream-to=origin/<branch> <branch> 5. Pull:
git pull`git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Respostas:
Importante: Se você tiver alterações locais, elas serão perdidas. Com ou sem
--hard
opção, quaisquer confirmações locais que não foram enviadas serão perdidas. [*]Se você tiver algum arquivo que não seja rastreado pelo Git (por exemplo, conteúdo do usuário enviado), esses arquivos não serão afetados.
Eu acho que este é o caminho certo:
Então, você tem duas opções:
OU Se você estiver em outro ramo:
Explicação:
git fetch
baixa a versão mais recente do controle remoto sem tentar mesclar ou refazer nada.Em seguida,
git reset
redefine o ramo mestre para o que você acabou de buscar. A--hard
opção altera todos os arquivos em sua árvore de trabalho para corresponder aos arquivos emorigin/master
Manter confirmações locais atuais
[*] : Vale a pena notar que é possível manter confirmações locais atuais criando uma ramificação
master
antes de redefinir:Depois disso, todos os commits antigos serão mantidos
new-branch-to-save-current-commits
.Alterações não confirmadas
Alterações não confirmadas, no entanto (mesmo preparadas), serão perdidas. Certifique-se de esconder e cometer o que precisar. Para isso, você pode executar o seguinte:
E, em seguida, reaplicar essas alterações não confirmadas:
fonte
git reset --hard origin/branch-name
git pull -f
git reflog
, que lista todas as confirmações, também aquelas sem base. Até você limpar sua cópia local usandogit gc
, tudo estará perdidoTente o seguinte:
Deve fazer o que você quiser.
fonte
AVISO:
git clean
exclui todos os seus arquivos / diretórios não rastreados e não pode ser desfeito.Às vezes simplesmente
clean -f
não ajuda. No caso de você não acompanhar o diretório, a opção -d também é necessária:AVISO:
git clean
exclui todos os seus arquivos / diretórios não rastreados e não pode ser desfeito.Considere usar o sinalizador
-n
(--dry-run
) primeiro. Isso mostrará o que será excluído sem excluir nada:Exemplo de saída:
fonte
.gitignore
git clean -dfx
. O-x
ignora .gitignore. Normalmente, seus produtos de compilação estarão em .gitignore.Como o Hedgehog, acho que as respostas são terríveis. Mas, embora a resposta de Hedgehog possa ser melhor, não acho que seja tão elegante quanto poderia ser. A maneira que descobri isso é usando "buscar" e "mesclar" com uma estratégia definida. O que deve garantir que as alterações locais sejam preservadas, desde que não sejam um dos arquivos com os quais você está tentando forçar uma substituição.
Primeiro faça um commit das suas alterações
Em seguida, busque as alterações e substitua se houver um conflito
"-X" é um nome de opção e "deles" é o valor dessa opção. Você está optando por usar as alterações "deles", em vez de "suas", se houver um conflito.
fonte
get fetch other-repo
; 2)git merge -s recursive -X theirs other-repo/master
git merge -X theirs origin/master
Em vez de fazer:
Eu recomendaria fazer o seguinte:
Não é necessário buscar todos os controles remotos e ramificações para redefinir a ramificação de origem / mestre, certo?
fonte
git add .
primeiro, antesgit reset --hard
Parece que a melhor maneira é fazer primeiro:
Para excluir todos os arquivos não rastreados e continuar com o procedimento usual
git pull
...fonte
git fetch origin && git reset --hard origin/master
git clean
melhor resposta é aqui? Parece que remover arquivos não é necessariamente o que o OP deseja. Eles pediram que a substituição de arquivos locais não fosse excluída.Atenção, isso excluirá permanentemente seus arquivos se você tiver alguma entrada de diretório / * no seu arquivo gitignore.
Algumas respostas parecem terríveis. Terrível no sentido do que aconteceu com @Lauri, seguindo a sugestão de David Avsajanishvili.
Em vez disso (git> v1.7.6):
Mais tarde, você pode limpar o histórico de stash.
Manualmente, um por um:
Brutalmente, tudo de uma vez:
Obviamente, se você quiser voltar ao que escondeu:
fonte
--include-untracked
simplesmente temporariamente - emgit add
todo o seu repositório e, em seguida, escondendo-o imediatamente.git stash apply
trouxe de volta todos os meus arquivos não rastreados, com a exceção (justamente) daqueles que a mesclagem já havia criado: "já existe, sem check-out". Funcionou perfeitamente.git stash -u
.Você pode achar este comando útil para descartar as alterações locais:
E, em seguida, faça uma limpeza (remove arquivos não rastreados da árvore de trabalho):
Se você deseja remover diretórios não rastreados, além de arquivos não rastreados:
fonte
Em vez de mesclar com
git pull
, tente o seguinte:git fetch --all
Seguido por:
git reset --hard origin/master
.fonte
A única coisa que funcionou para mim foi:
Isso levará de volta cinco commits e depois com
Eu descobri isso pesquisando como desfazer uma mesclagem do Git .
fonte
work around
mas realmente eficaz. Como alguns conflitos podem ocorrer apenas em poucas confirmações, a reversão de 5 confirmações garantirá que não haja conflitos com o código remoto.O problema com todas essas soluções é que elas são muito complexas ou, um problema ainda maior, é que elas removem todos os arquivos não rastreados do servidor da Web, o que não queremos, pois sempre há arquivos de configuração necessários que estão em uso. o servidor e não no repositório Git.
Aqui está a solução mais limpa que estamos usando:
O primeiro comando busca os dados mais recentes.
O segundo comando verifica se há arquivos que estão sendo adicionados ao repositório e exclui esses arquivos não rastreados do repositório local, o que causaria conflitos.
O terceiro comando faz check-out de todos os arquivos que foram modificados localmente.
Finalmente, fazemos um esforço para atualizar para a versão mais recente, mas desta vez sem conflitos, pois os arquivos não rastreados que estão no repositório não existem mais e todos os arquivos modificados localmente já são os mesmos do repositório.
fonte
git merge origin/master
será mais rápido e provavelmente ainda mais seguro. Como se alguém enviasse novas alterações durante a remoção dos arquivos desse script (o que provavelmente não acontecerá, mas é possível), toda a solicitação poderá falhar. A única razão que coloqueipull
lá é porque alguém pode não estar trabalhando no ramo principal, mas em outro ramo e eu queria que o script fosse universal..gitignore
.Primeiro de tudo, tente da maneira padrão:
Aviso : Os comandos acima podem resultar em perda de dados / arquivos somente se você não os confirmar! Se você não tiver certeza, faça o backup primeiro de toda a pasta do repositório.
Em seguida, puxe-o novamente.
Se o procedimento acima não ajudar e você não se importar com seus arquivos / diretórios não rastreados (faça o backup primeiro, por precaução), tente as seguintes etapas simples:
Isso REMOVERá todos os arquivos git (excempt
.git/
dir, onde você tem todos os commit) e o puxará novamente.Por que
git reset HEAD --hard
poderia falhar em alguns casos?Regras personalizadas em
.gitattributes file
Tendo
eol=lf
regra em .gitattributes pode fazer com que o git modifique algumas alterações de arquivo, convertendo as terminações de linha CRLF em LF em alguns arquivos de texto.Se for esse o caso, você deve confirmar essas alterações de CRLF / LF (revisando-as
git status
) ou tente:git config core.autcrlf false
ignorá-las temporariamente.Incompatibilidade do sistema de arquivos
Quando você estiver usando um sistema de arquivos que não suporta atributos de permissão. No exemplo, você tem dois repositórios, um no Linux / Mac (
ext3
/hfs+
) e outro no sistema de arquivos baseado em FAT32 / NTFS.Como você percebe, existem dois tipos diferentes de sistemas de arquivos, então o que não suporta permissões Unix basicamente não pode redefinir as permissões de arquivos no sistema que não suporta esse tipo de permissões, portanto, não importa como
--hard
você tente, git sempre detecte algumas "alterações".fonte
Eu tive o mesmo problema. Ninguém me deu essa solução, mas funcionou para mim.
Eu resolvi isso por:
.git
diretório.git reset --hard HEAD
git pull
git push
Agora funciona.
fonte
Bônus:
Ao falar sobre puxar / buscar / mesclar nas respostas anteriores, gostaria de compartilhar um truque interessante e produtivo,
git pull --rebase
Este comando acima é o comando mais útil na minha vida no Git, que economizou muito tempo.
Antes de enviar o commit recentemente ao servidor, tente este comando e ele sincronizará automaticamente as alterações mais recentes do servidor (com uma busca + mesclagem) e colocará o commit no topo do log do Git. Não há necessidade de se preocupar com puxar / mesclar manualmente.
Encontre detalhes em O que "git pull --rebase" faz? .
fonte
git pull -r
.Eu tive um problema parecido. Eu tive que fazer isso:
fonte
git clean
com cautelaResumi outras respostas. Você pode executar
git pull
sem erros:Aviso : este script é muito poderoso, para que você possa perder suas alterações.
fonte
git reset --hard HEAD
possa ser redundante; minha página de manual local (2.6.3) diz quereset
na segunda linhagit reset --hard origin/master
"o padrão é HEAD de todas as formas".Com base em minhas próprias experiências semelhantes, a solução oferecida por Strahinja Kustudic acima é de longe a melhor. Como outros já apontaram, a simples reinicialização total removerá todos os os arquivos não rastreados, que podem incluir muitas coisas que você não deseja remover, como arquivos de configuração. O mais seguro é remover apenas os arquivos que estão prestes a serem adicionados e, nesse caso, é provável que você também deseje fazer check-out dos arquivos modificados localmente que estão prestes a serem atualizados.
Com isso em mente, atualizei o script de Kustudic para fazer exatamente isso. Também corrigi um erro de digitação (um ausente 'no original).
fonte
Acredito que existem duas causas possíveis de conflito, que devem ser resolvidas separadamente e, até onde sei, nenhuma das respostas acima lida com os dois:
Os arquivos locais não rastreados precisam ser excluídos, manualmente (mais seguro) ou conforme sugerido em outras respostas,
git clean -f -d
As confirmações locais que não estão na ramificação remota também precisam ser excluídas. Na IMO, a maneira mais fácil de conseguir isso é:
git reset --hard origin/master
(substitua 'master' por qualquer filial em que você esteja trabalhando e execute pelagit fetch origin
primeira vez)fonte
Uma maneira mais fácil seria:
Isso substituirá seu arquivo local pelo arquivo no git
fonte
Parece que a maioria das respostas aqui está focada no
master
ramo; no entanto, há momentos em que estou trabalhando no mesmo ramo de recursos em dois lugares diferentes e quero que uma rebase em um seja refletida no outro sem muito esforço.Com base em uma combinação de resposta de RNA e resposta de Torek a uma pergunta semelhante , eu vim acima com este que funciona esplendidamente:
Execute isso a partir de uma ramificação e ela redefinirá apenas sua ramificação local para a versão upstream.
Isso pode ser bem colocado em um alias do git (
git forcepull
):git config alias.forcepull "!git fetch ; git reset --hard @{u}"
Ou, no seu
.gitconfig
arquivo:Aproveitar!
fonte
Eu tive o mesmo problema e, por algum motivo, até um
git clean -f -d
não o faria. Aqui está o porquê: Por algum motivo, se o seu arquivo for ignorado pelo Git (via uma entrada .gitignore, presumo), ele ainda se preocupa em substituí-lo com um puxão posterior , mas uma limpeza não o removerá, a menos que você o adicione-x
.fonte
Conheço um método muito mais fácil e menos doloroso:
É isso aí!
fonte
Acabei de resolver isso sozinho:
onde o último comando fornece uma lista de quais foram suas alterações locais. Continue modificando a ramificação "tmp" até que seja aceitável e, em seguida, retorne ao master com:
Da próxima vez, você provavelmente poderá lidar com isso de uma maneira mais limpa pesquisando "git stash branch", embora o stash provavelmente cause problemas nas primeiras tentativas, faça o primeiro experimento em um projeto não crítico ...
fonte
Eu tenho uma situação estranha que nem
git clean
ougit reset
obras. Eu tenho que remover o arquivo conflitantegit index
usando o seguinte script em todos os arquivos não rastreados:Então eu sou capaz de puxar muito bem.
fonte
git fetch --all && git reset --hard origin/master && git pull
fonte
Apesar da pergunta original, as principais respostas podem causar problemas para pessoas que têm um problema semelhante, mas não querem perder seus arquivos locais. Por exemplo, consulte os comentários de Al-Punk e crizCraig.
A versão a seguir confirma as alterações locais em uma ramificação temporária (
tmp
), verifica a ramificação original (que eu suponho que sejamaster
) e mescla as atualizações. Você poderia fazer isso comstash
, mas eu descobri que geralmente é mais fácil simplesmente usar a abordagem de ramificação / mesclagem.onde assumimos que o outro repositório está
origin master
.fonte
Esses quatro comandos funcionam para mim.
Para verificar / puxar após executar esses comandos
Eu tentei muito, mas finalmente obtive sucesso com esses comandos.
fonte
Apenas faça
Assim, você evita todos os efeitos colaterais indesejados, como excluir arquivos ou diretórios que deseja manter etc.
fonte
Redefina o índice e a cabeça para
origin/master
, mas não redefina a árvore de trabalho:fonte
Requisitos:
Solução:
Busque com uma limpeza de arquivos e diretórios, ignorando .gitignore e redefinição total da origem .
fonte