Como forçar o “git pull” para substituir arquivos locais?

7189

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.

Jakub Troszok
fonte
17
alguém lendo isso que acha que pode perder arquivos, eu estive nessa posição e achei que o buffer do Sublime Text me salvou - se estou trabalhando em alguma coisa, exclua acidentalmente tudo tentando resolver um problema semelhante a esse ou usando uma resposta a esta pergunta e os arquivos foram abertos no Sublime (o que há uma boa chance de), então os arquivos ainda existirão no Sublime, apenas ali ou no histórico de desfazer
Toni Leigh
63
git reset --hard origin/branch_to_overwrite
Andrew Atkinson
1
basicamente, apenas faça um pull do desenvolvimento após o checkout inicial -b. fazer o seu trabalho, em seguida, empurre para dentro.
ldgorman
1
Resposta curta: excluir e recriar ramificações. 1. Exclua a ramificação: git branch <branch> -D2. Redefina para uma confirmação antes do conflito: git reset <commit> --hard3. 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`
Nino Filiu
1
Para alterar todos os finais de CRLF para LF, (inicie a limpeza)git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Chloe

Respostas:

10041

Importante: Se você tiver alterações locais, elas serão perdidas. Com ou sem --hardopçã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:

git fetch --all

Então, você tem duas opções:

git reset --hard origin/master

OU Se você estiver em outro ramo:

git reset --hard origin/<branch_name>

Explicação:

git fetch baixa a versão mais recente do controle remoto sem tentar mesclar ou refazer nada.

Em seguida, git resetredefine o ramo mestre para o que você acabou de buscar. A --hardopçã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 masterantes de redefinir:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

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:

git stash

E, em seguida, reaplicar essas alterações não confirmadas:

git stash pop
RNA
fonte
14
Cuidado! Se você tiver confirmações locais não enviadas, isso as removerá do seu ramo! Essa solução mantém os arquivos não rastreados não no repositório intactos, mas substitui todo o resto.
Matthijs P
479
É uma pergunta popular, por isso gostaria de esclarecer o comentário principal aqui. Acabei de executar comandos como descrito nesta resposta e ele não removeu TODOS os arquivos locais. Somente os arquivos rastreados remotamente foram substituídos e todos os arquivos locais que estiveram aqui foram deixados intocados.
Vermelho
14
no caso de você está puxando a partir de um repo que tem o seu nome filial remota diferente de "mestre", o usogit reset --hard origin/branch-name
Nerrve
97
Dada a quantidade de votos positivos para essa pergunta e resposta, acho que o git deve incorporar um comando como:git pull -f
Sophivorus
7
Confirmações que não foram enviadas antes que a redefinição forçada possa ser recuperada usando git reflog, que lista todas as confirmações, também aquelas sem base. Até você limpar sua cópia local usando git gc, tudo estará perdido
Koen.
935

Tente o seguinte:

git reset --hard HEAD
git pull

Deve fazer o que você quiser.

Travis Reeder
fonte
16
Eu fiz isso e alguns arquivos locais que não estavam mais no repositório foram deixados no disco.
Piotr Owsiak
26
Eu não acho que isso esteja correto. o acima fará uma mesclagem, não substituirá, o que foi solicitado na pergunta: "Como forçar o git a substituí-los?" Eu não tenho a resposta, atualmente estou procurando por ela .. no momento em que mudo para a ramificação com o código que eu quero manter "git checkout BranchWithCodeToKeep", então "git branch -D BranchToOverwrite" e finalmente "git checkout -b BranchToOverwrite". agora você terá o código exato de BranchWithCodeToKeep na filial BranchToOverwrite sem precisar executar uma mesclagem.
felbus
252
em vez de juntar usando 'git pull', tente git fetch --all seguido por 'git redefinir --hard origem / master'
Lloyd Moore
5
sim, a solução @lloydmoore funcionou para mim. Poderia ser uma resposta e não apenas um comentário.
Max Williams
2
Isso redefinirá as alterações atuais de volta ao último commit de ramificação extraído. Em seguida, o git pull mescla as alterações da ramificação mais recente. Isso fez exatamente o que eu queria que fizesse .. Obrigado!
Codeversed
459

AVISO: git cleanexclui todos os seus arquivos / diretórios não rastreados e não pode ser desfeito.


Às vezes simplesmente clean -fnão ajuda. No caso de você não acompanhar o diretório, a opção -d também é necessária:

# WARNING: this can't be undone!

git reset --hard HEAD
git clean -f -d
git pull

AVISO: git cleanexclui 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:

git clean -n -f -d

Exemplo de saída:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
David Avsajanishvili
fonte
33
Impressionante ... Corri isso contra o meu repositório dotfiles ... No meu diretório pessoal. Bom que eu realmente não tenho nada importante lá ...
Lauri
7
Acho que a descrição do cenário deixa claro que ele realmente não quer jogar fora o conteúdo. Antes, o que ele quer é parar o git baulking de substituir os arquivos. @ Lauri, isso não deveria ter acontecido com você. Infelizmente, as pessoas parecem ter interpretado mal a essência da descrição do cenário - veja minha sugestão.
Hedgehog
19
FINALMENTE . O git clean -f -d é útil quando make clean falha ao limpar tudo.
earthmeLon
7
@crizCraig a menos que eles são adicionados.gitignore
Bleeding Fingers
5
@earthmeLon, para o que você desejar git clean -dfx. O -xignora .gitignore. Normalmente, seus produtos de compilação estarão em .gitignore.
Paul Draper
384

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

 git add *
 git commit -a -m "local file server commit message"

Em seguida, busque as alterações e substitua se houver um conflito

 git fetch origin master
 git merge -s recursive -X theirs origin/master

"-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.

Richard Kersey
fonte
56
Esta é a melhor resposta que eu vi até agora. Eu não tentei, mas, ao contrário de outras respostas, isso não tenta destruir todos os seus arquivos não rastreados, o que é muito perigoso por razões óbvias.
huyz
5
Idem - isso funcionou para mim ao fazer uma mesclagem muito grande (solicitação pull do GitHub), onde eu só queria aceitar tudo isso em cima do que tinha. Boa resposta! No meu caso, os dois últimos comandos foram: 1) get fetch other-repo; 2)git merge -s recursive -X theirs other-repo/master
quux00 27/07/12
2
Isso substituirá qualquer conflito com os arquivos do repositório e não com os locais, correto?
Nathan F.
2
Melhor resposta. A resposta mais alta aceita me deixou no meu caso com a cabeça desapegada. Eu mudei para branch master local e correugit merge -X theirs origin/master
petergus
2
O problema com esta (excelente) resposta é que ela adiciona todos os arquivos locais, que às vezes podem não ser o que você deseja. Você pode apenas querer adicionar os arquivos específicos que foram omitidos. Mas a melhor coisa é que ele faz o que deveria ter feito - adicione-os localmente. Você provavelmente não precisará da estratégia deles -X, pois eles têm a mesma imagem. Na verdade, eu sugiro deixá-lo de fora primeiro, apenas para descobrir se há alguma anomalia e adicioná-lo, se houver, depois de revisar que o 'deles' é sempre a escolha correta. Mas então, eu sou paranóico.
precisa
279

Em vez de fazer:

git fetch --all
git reset --hard origin/master

Eu recomendaria fazer o seguinte:

git fetch origin master
git reset --hard origin/master

Não é necessário buscar todos os controles remotos e ramificações para redefinir a ramificação de origem / mestre, certo?

Johanneke
fonte
3
Sua resposta é exatamente o que você precisava para o seu representante. Devo perguntar, isso também remove todos os arquivos não rastreados?
Nicolas De Jay
5
Sim, a maioria dos meus representantes vem daqui :) Isso também removerá todos os arquivos não rastreados. Algo que eu tinha esquecido e foi dolorosamente lembrados de apenas 2 dias atrás ...
Johanneke
1
Ver os comentários sobre esta outra resposta: stackoverflow.com/a/8888015/2151700
Johanneke
Isso não removeu meus arquivos não rastreados; o que é realmente o que eu esperaria. Existe alguma razão para algumas pessoas e não para outras?
Arichards
Arquivos não rastreados não são afetados pelo git reset. Se você deseja que eles sejam removidos também, faça git add .primeiro, antesgit reset --hard
Johanneke
131

Parece que a melhor maneira é fazer primeiro:

git clean

Para excluir todos os arquivos não rastreados e continuar com o procedimento usual git pull...

Jakub Troszok
fonte
4
Tentei usar o "git clean" para resolver o mesmo problema, mas ele não o resolveu. O status git diz "Sua ramificação e 'origem / mestre' divergiram, # e possuem 2 e 9 confirmações diferentes cada, respectivamente." e o git pull diz algo semelhante ao que você tem acima.
slacy 24/09/09
43
O git clean é um instrumento bastante contundente e pode jogar fora muitas coisas que você pode querer manter. Melhor remover ou renomear os arquivos dos quais o git está reclamando até que o pull seja bem-sucedido.
Neil Mayhew
2
Eu não acho que isso funcione em geral. Não existe uma maneira de fazer basicamente um clone remoto do git através de um puxão forçado do git?
mathtick 29/11
10
@mathick:git fetch origin && git reset --hard origin/master
Arrowmaster
3
A git cleanmelhor 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.
JohnAllen
111

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):

git stash --include-untracked
git pull

Mais tarde, você pode limpar o histórico de stash.

Manualmente, um por um:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

Brutalmente, tudo de uma vez:

$ git stash clear

Obviamente, se você quiser voltar ao que escondeu:

$ git stash list
...
$ git stash apply stash@{5}
Ouriço
fonte
2
Não, eu não penso assim. O armazenamento em cache apenas remove os arquivos não confirmados. O acima também move (oculta) arquivos que o git não rastreia. Isso evita que os arquivos que foram adicionados ao controle remoto ainda não foram puxados para a sua máquina - mas que você criou (!) - sejam puxados para baixo. Tudo sem destruir o trabalho não comprometido. Espero que isso faça sentido?
Hedgehog
3
Se você não possui o 1.7.6, pode imitá-lo --include-untrackedsimplesmente temporariamente - em git addtodo o seu repositório e, em seguida, escondendo-o imediatamente.
Nategood #
3
Eu concordo com Hedgehog. Se você fizer as respostas populares aqui, provavelmente descobrirá que matou inadvertidamente muitas coisas que realmente não queria perder.
Guardius
1
Eu tinha outros arquivos não rastreados - além daquele que o merge / pull queria sobrescrever, então essa solução funcionou melhor. git stash applytrouxe 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.
BigBlueHat
2
Essa é a resposta mais limpa e deve ser a aceita. Para reduzir a digitação você pode usar o pequeno formulário: git stash -u.
Ccpizza 23/03
93

Você pode achar este comando útil para descartar as alterações locais:

git checkout <your-branch> -f

E, em seguida, faça uma limpeza (remove arquivos não rastreados da árvore de trabalho):

git clean -f

Se você deseja remover diretórios não rastreados, além de arquivos não rastreados:

git clean -fd
Vishal
fonte
Acho que a descrição do cenário deixa claro que ele realmente não quer jogar fora o conteúdo. Antes, o que ele quer é parar o git baulking de substituir os arquivos. Veja minha sugestão.
Hedgehog
3
Embora essa resposta possa não se encaixar exatamente na descrição, ela ainda me salvou da frustração de o git mexer nos retornos de carro (evento com autocrlf false). Quando o git reset --hard HEAD não deixa você com "nenhum" arquivo modificado, esses sinalizadores "-f" são bastante úteis. Muito obrigado.
Kellindil
88

Em vez de mesclar com git pull, tente o seguinte:

git fetch --all

Seguido por:

git reset --hard origin/master.

Lloyd Moore
fonte
61

A única coisa que funcionou para mim foi:

git reset --hard HEAD~5

Isso levará de volta cinco commits e depois com

git pull

Eu descobri isso pesquisando como desfazer uma mesclagem do Git .

Chris BIllante
fonte
Este foi o que finalmente funcionou para mim como eu tive força empurrou meu ramo para o repo origem e continuei recebendo conflitos de mesclagem ao tentar puxá-lo para o meu repo remoto ..
jwfrench
Oi, na verdade, este é um truque para um, work aroundmas 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.
Hoang Le
54

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:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • 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.

Strahinja Kustudic
fonte
Usar "git merge origin / master" como a última linha (como você diz na sua nota) em vez de "git pull" será mais rápido, pois você já retirou as alterações do repositório git.
Josh
1
Sim, claro, git merge origin/masterserá 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 coloquei pulllá é porque alguém pode não estar trabalhando no ramo principal, mas em outro ramo e eu queria que o script fosse universal.
Strahinja Kustudic 01/09/13
Se você criou arquivos localmente, como arquivos de opção, insira-os .gitignore.
quer
52

Primeiro de tudo, tente da maneira padrão:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

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:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Isso REMOVERá todos os arquivos git (excempt .git/dir, onde você tem todos os commit) e o puxará novamente.


Por que git reset HEAD --hardpoderia falhar em alguns casos?

  1. 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 falseignorá-las temporariamente.

  2. 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 --hardvocê tente, git sempre detecte algumas "alterações".

kenorb
fonte
47

Eu tive o mesmo problema. Ninguém me deu essa solução, mas funcionou para mim.

Eu resolvi isso por:

  1. Exclua todos os arquivos. Deixe apenas o .gitdiretório.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Agora funciona.

John John Pichler
fonte
1
O mesmo aqui. Às vezes, apenas as obras solução muito duras, isso acontece muitas vezes que apenas repor e limpo não são suficientes alguma forma ...
jdehaan
41

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? .

Sazzad Hissain Khan
fonte
3
Em suma: git pull -r.
Kenorb # 15/19
29

Eu tive um problema parecido. Eu tive que fazer isso:

git reset --hard HEAD
git clean -f
git pull
Ryan
fonte
6
use git cleancom cautela
nategood 30/03/12
29

Resumi outras respostas. Você pode executar git pullsem erros:

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Aviso : este script é muito poderoso, para que você possa perder suas alterações.

Robert Moon
fonte
2
Isso substituirá os arquivos modificados (arquivos que foram registrados anteriormente) e removerá os arquivos não rastreados (arquivos que nunca foram registrados). Exatamente o que eu estava procurando, obrigado!
Styfle 03/03
3
Eu suspeito que a terceira linha git reset --hard HEADpossa ser redundante; minha página de manual local (2.6.3) diz que resetna segunda linha git reset --hard origin/master "o padrão é HEAD de todas as formas".
Arichards
2
@arichards Acho que seu suspeito está certo, mas se a segunda linha não funcionar (por qualquer motivo), a terceira linha funcionará bem para redefinir. Esta solução não precisa ser otimizada. Acabei de resumir outras respostas. Isso é tudo. Obrigado pelo seu comentário. :)
Robert Moon
28

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).

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull
Rolf Kaiser
fonte
Usar "git merge origin / master" como a última linha (como você diz na sua nota) em vez de "git pull" será mais rápido, pois você já retirou as alterações do repositório git.
Josh
A verificação dos arquivos modificados é necessária, portanto, isso funciona 100% das vezes. Atualizei meu script com isso há muito tempo, mas esqueci de atualizar aqui também. Eu também uso um pouco diferente de você. Eu faço check-out de arquivos com qualquer tipo de modificação, não apenas M, por isso funciona o tempo todo.
Strahinja Kustudic 01/09/2013
24

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 pela git fetch originprimeira vez)

tiho
fonte
22

Uma maneira mais fácil seria:

git checkout --theirs /path/to/file.extension
git pull origin master

Isso substituirá seu arquivo local pelo arquivo no git

maximus 69
fonte
21

Parece que a maioria das respostas aqui está focada no masterramo; 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:

git fetch
git reset --hard @{u}

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 .gitconfigarquivo:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Aproveitar!

JacobEvelyn
fonte
Essa resposta também é boa porque funciona independentemente de qual filial você está!
leafmeal
19

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.

Tierlieb
fonte
19

Conheço um método muito mais fácil e menos doloroso:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

É isso aí!

ddmytrenko
fonte
18

Acabei de resolver isso sozinho:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

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:

git checkout master && git merge tmp

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 ...

Simon B.
fonte
17

Eu tenho uma situação estranha que nem git cleanou git resetobras. Eu tenho que remover o arquivo conflitante git indexusando o seguinte script em todos os arquivos não rastreados:

git rm [file]

Então eu sou capaz de puxar muito bem.

Chen Zhang
fonte
16

git fetch --all && git reset --hard origin/master && git pull

Suge
fonte
14

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 seja master) e mescla as atualizações. Você poderia fazer isso com stash, mas eu descobri que geralmente é mais fácil simplesmente usar a abordagem de ramificação / mesclagem.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

git fetch origin master
git merge -s recursive -X theirs origin master

onde assumimos que o outro repositório está origin master.

Snowcrash
fonte
13

Esses quatro comandos funcionam para mim.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Para verificar / puxar após executar esses comandos

git pull origin master

Eu tentei muito, mas finalmente obtive sucesso com esses comandos.

vishesh chandra
fonte
2
"git branch -D master" exclui o ramo. então tenha cuidado com isso. Prefiro usar "git checkout origin / master -b <novo nome da filial>", que cria uma nova ramificação com um novo nome e você precisa de 3,4 linhas. Também é recomendável usar o "git clean -f" também.
Chand Priyankara
13

Apenas faça

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

Assim, você evita todos os efeitos colaterais indesejados, como excluir arquivos ou diretórios que deseja manter etc.

user2696128
fonte
12

Redefina o índice e a cabeça para origin/master, mas não redefina a árvore de trabalho:

git reset origin/master

fonte
Pessoalmente, achei isso muito útil. Ele mantém sua árvore de trabalho para que você possa fazer o check-in novamente. Para o meu problema, eu excluí os mesmos arquivos que foram adicionados para que fiquem presos. Estranho, eu sei.
Jason Sebring
12

Requisitos:

  1. Acompanhe as alterações locais para que ninguém aqui as perca.
  2. Faça o repositório local corresponder ao repositório de origem remoto.

Solução:

  1. Esconda as alterações locais.
  2. Busque com uma limpeza de arquivos e diretórios, ignorando .gitignore e redefinição total da origem .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
vezenkov
fonte