Como é que obrigo o "git pull" a sobrepor os ficheiros locais?

Como forço uma sobreposição de ficheiros locais num git pull?

o cenário é o seguinte:

  • um membro da equipa está a modificar os modelos de um site em que estamos a trabalhar
  • estão a adicionar algumas imagens ao directório de imagens (mas esquece-se de as Adicionar sob controlo de origem)
  • Estão a enviar as imagens por correio, mais tarde, para mim.
  • estou a adicionar as imagens sob o controlo da fonte e a empurrá-las para o GitHub juntamente com outras alterações
  • Eles não é possível obter actualizações do GitHub porque o Git não quer sobrepor os seus ficheiros.

Este é o erro que estou a obter:

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge
Como é que obrigo o Git a sobrepô-los? A pessoa é um designer-geralmente eu resolvo todos os conflitos à mão, de modo que o servidor tem a versão mais recente que eles só precisam atualizar em seu computador.

Author: JimHawkins, 2009-07-14

30 answers

Importante: se tiver alterações locais, estas serão perdidas. Com ou sem opção --hard, todos os commits locais que não tenham sido empurrados serão perdidos.[*]

Se tiver quaisquer ficheiros que não sejamrastreados pelo Git (por exemplo, conteúdo carregado do utilizador), estes ficheiros não serão afectados.


Acho que este é o caminho certo.
git fetch --all

Então, tens duas opções:

git reset --hard origin/master

Ou se estiver a tomar outro ramo:

git reset --hard origin/<branch_name>

Explicação:

git fetch descarrega as últimas informações do remote sem tentar fundir ou refazer nada.

Então o git reset repõe o ramo mestre para o que você acabou de obter. A opção --hard altera todos os ficheiros na sua árvore de trabalho para corresponder aos ficheiros em origin/master


Manter os actuais commits locais

[*]: vale a pena notar que é possível manter os commits locais atuais criando um branch de master antes nova fixação:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master
Depois disto, todos os antigos commits serão guardados em new-branch-to-save-current-commits.

Alterações por persistir

As alterações por persistir, no entanto (mesmo encenadas), serão perdidas. Certifica-te de guardar e enviar tudo o que precisares. Para isso você pode executar o seguinte:

git stash

E, em seguida, reaplicar estas alterações não autorizadas:

git stash pop
 7543
Author: RNA, 2018-07-17 21:53:17

Tenta isto:

git reset --hard HEAD
git pull
Deve fazer o que quiseres.
 774
Author: Travis Reeder, 2017-01-14 15:10:38

Atenção: git clean apaga todos os seus ficheiros/directórios não rastreados e não pode ser desfeito.


Às vezes apenas clean -f não ajuda. No caso de ter pastas não-rastreadas, a opção d também é necessária:

# WARNING: this can't be undone!

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

Atenção: git clean apaga todos os seus ficheiros/directórios não rastreados e não pode ser desfeito.

Considere a utilização de {MM / AAAA}-n (--dry-run) bandeira primeiro. Isto mostrar-lhe-á o que será apagado sem apagar de facto nada:

git clean -n -f -d
Exemplo resultado:
Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
 389
Author: David Avsajanishvili, 2018-08-17 19:32:32
Como o Ouriço, acho que as respostas são terríveis. Mas embora a resposta do ouriço possa ser melhor, não acho que seja tão elegante como poderia ser. A maneira que eu encontrei para fazer isso é usando "fetch" e "merge" com uma estratégia definida. O que deve fazê-lo de modo que suas mudanças locais são preservadas, desde que não sejam um dos arquivos que você está tentando forçar uma sobreposição com.

Primeiro faça um commit das suas alterações

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

Depois obter as alterações e sobrepor se existir is a conflict

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

" - X "é um nome de opção, e" deles " é o valor para essa opção. Você está escolhendo usar" suas "mudanças, em vez de" suas " mudanças se houver um conflito.

 339
Author: Richard Kersey, 2017-02-23 13:45:53

Em vez de fazer:

git fetch --all
git reset --hard origin/master
Eu aconselharia fazer o seguinte:
git fetch origin master
git reset --hard origin/master

Não é necessário obter todos os comandos e ramos se você vai reiniciar para o ramo original/mestre direito?

 242
Author: Johanneke, 2016-09-14 09:46:30

Parece que a melhor maneira é fazer primeiro:

git clean

Para Apagar todos os ficheiros não rastreados e depois continuar com o habitual git pull...

 124
Author: Jakub Troszok, 2017-01-14 15:10:01

Atenção, ao fazer isto, irá apagar permanentemente os seus ficheiros se tiver quaisquer itens de directório/* no seu ficheiro gitignore.

Algumas respostas parecem ser terríveis. Terrível no sentido do que aconteceu com @Lauri seguindo a sugestão de David Avsajanishvili.

Em vez de (git > v1.7.6):

git stash --include-untracked
git pull
Depois podes limpar o histórico do esconderijo.

Manualmente, um a 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, de uma só vez.
$ git stash clear
Claro, se quiseres voltar. ao que escondeste.
$ git stash list
...
$ git stash apply stash@{5}
 99
Author: Hedgehog, 2018-03-07 07:00:46

Poderá achar este comando útil para eliminar as alterações Locais:

git checkout <your-branch> -f

E depois fazer uma limpeza (remove os ficheiros não rastreados da árvore de trabalho):

git clean -f

Se quiser remover as pastas não rastreadas para além dos ficheiros não rastreados:

git clean -fd
 86
Author: Vishal, 2017-01-14 15:12:22

Em vez de se fundir com {[[0]}, tente isto:

git fetch --all

Seguida de:

git reset --hard origin/master.

 76
Author: Lloyd Moore, 2018-03-21 07:21:12
A única coisa que funcionou para mim foi:
git reset --hard HEAD~5
Isto leva-te de volta cinco commits e depois com
git pull

Descobri isso olhando para cima como desfazer uma junção Git .

 53
Author: Chris BIllante, 2017-05-23 10:31:37

O problema com todas estas soluções é que elas são todas muito complexas, ou, um problema ainda maior, é que elas removem todos os arquivos não rastreados do servidor web, o que nós não queremos, uma vez que há sempre Arquivos de configuração necessários que estão no servidor e não no repositório Git.

Aqui está a solução mais limpa que estamos a usar:

# 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 obtém os dados mais recentes.

  • O segundo comando verifica se há algum arquivos que estão sendo adicionados ao repositório e apaga aqueles arquivos não rastreados do repositório local que causariam conflitos.

  • O terceiro comando verifica todos os arquivos que foram modificados localmente.

  • Finalmente nós fazemos um pull para atualizar para a versão mais nova, mas desta vez sem quaisquer conflitos, uma vez que os arquivos não rastreados que estão no repo não existem mais e todos os arquivos modificados localmente são já o mesmo que no repositorio.

 50
Author: Strahinja Kustudic, 2014-05-23 21:14:30
Tive o mesmo problema. Ninguém me deu esta solução, mas funcionou comigo. Resolvi-o por:
  1. apagar todos os ficheiros. Deixa só o ... directório git.
  2. git reset --hard HEAD
  3. git pull
  4. git push
Agora funciona.
 38
Author: John John Pichler, 2014-05-23 21:09:53
Em primeiro lugar, tente o método padrão.
git reset HEAD --hard # Remove all not committed changes

Se acima não ajudar e não se importar com os seus ficheiros/directórios não rastreados( faça a cópia de segurança em primeiro lugar só para o caso), tente os seguintes passos 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

Isto irá remover todos os ficheiros git (excempt .git/ dir, onde você tem todos os commits) e puxá-lo de novo.


Por que git reset HEAD --hard poderia falhar em alguns casos?

  1. Regras aduaneiras em .gitattributes file

    Ter eol=lf governado .os gitatributes poderiam Faça com que o git modifique algumas alterações de ficheiros, convertendo as terminações de linha do CRLF para o LF em alguns ficheiros de texto.

    Se for esse o caso, você tem que enviar estas alterações CRLF / LF( revendo-as em git status), ou tentar: git config core.autcrlf false para ignorá-las temporariamente.

  2. Sistema de Ficheiros incompleto

    Quando está a usar um sistema de ficheiros que não suporta atributos de permissões. Por exemplo, você tem dois repositórios, um no Linux / Mac (ext3/hfs+) e outra na base FAT32 / NTFS sistema.

    Como vê, existem dois tipos diferentes de sistemas de ficheiros, por isso o que não suporta as permissões do Unix, basicamente, não consegue repor as permissões do ficheiro no sistema que não suporta esse tipo de permissões, por isso, não importa como --hard tente, o git detecta sempre algumas "alterações".

 32
Author: kenorb, 2015-09-30 08:30:43
Tive um problema semelhante. Tinha de fazer isto.
git reset --hard HEAD
git clean -f
git pull
 27
Author: Ryan, 2011-11-06 16:35:34

Resumi outras respostas. Você pode executar git pull sem erros:

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

Atenção : este script é muito poderoso, então você pode perder suas mudanças.

 26
Author: Robert Moon, 2017-01-14 15:42:28
Com base nas minhas experiências semelhantes, a solução oferecida por Strahinja Kustudic acima é de longe a melhor. Como outros já salientaram, simplesmente fazer um reset rígido irá remover todos os ficheiros não rastreados que poderão incluir muitas coisas que não deseja remover, como ficheiros de configuração. O que é mais seguro, é remover apenas os arquivos que estão prestes a ser adicionados, e por isso, você provavelmente também gostaria de verificar quaisquer arquivos localmente modificados que estão prestes a ser actualizacao.

Isso em mente, eu atualizei o script do Kustudic para fazer exatamente isso. Eu também corrigi um typo (um faltando ' 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
 25
Author: Rolf Kaiser, 2015-08-13 23:12:27

Bónus:

Ao falar em puxar / buscar / mesclar nas respostas anteriores, gostaria de partilhar um truque interessante e produtivo,

git pull --rebase

Este comando acima é o comando mais útil na minha vida Git que salvou muito tempo.

Antes de carregar com o seu novo envio para o servidor, tente este comando e ele irá sincronizar automaticamente as últimas alterações do servidor (com uma junção fetch+) e irá colocar o seu envio no topo no registo Git. Não há. qualquer necessidade de se preocupar com o puxão/junção manual.

Encontra os detalhes em o que é que "git puxa --rebase" faz?.

 25
Author: Sazzad Hissain Khan, 2018-04-27 13:02:41
Eu acredito que existem duas causas possíveis de conflito, que devem ser resolvidas separadamente, e tanto quanto eu posso dizer nenhuma das respostas acima lida com ambas:
  • Os arquivos locais que não são rastreados precisam ser apagados manualmente (Mais Seguro) ou como sugerido em outras respostas, por git clean -f -d

  • Os commits locais que não estão no ramo remoto precisam ser excluídos também. IMO a maneira mais fácil de conseguir isto é com: git reset --hard origin/master (substitua 'master' por qualquer ramo que seja a trabalhar e executar um git fetch origin primeiro)

 22
Author: tiho, 2011-12-12 20:05:07

Uma maneira mais fácil seria:

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

Isto irá sobrepor o seu ficheiro local com o ficheiro no git

 20
Author: maximus 69, 2015-05-05 08:03:29

Parece que a maioria das respostas aqui estão focadas no ramo {[[2]}; no entanto, há alturas em que estou a trabalhar no mesmo ramo de recurso em dois locais diferentes e quero um rebase em um para ser reflectido no outro sem muito saltar através de aros.

Com base numa combinação da resposta de RNA e da resposta de Tarek a uma pergunta semelhante , descobri isto que funciona esplendidamente:
git fetch
git reset --hard @{u}
Faz isto a partir de um ramo e ele só vai reiniciar o teu ramificação local para a versão upstream.

Isto pode ser bem colocado num pseudónimo git (git forcepull) bem como:

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Ou, no seu ficheiro .gitconfig:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"
Divirtam-se!
 19
Author: JacobEvelyn, 2017-05-23 12:18:32
Tive o mesmo problema e, por alguma razão, nem um deles o faria. Eis a razão: por alguma razão, se o seu ficheiro for ignorado pelo Git (via a.o item do gitignore, presumo), ainda se preocupa em sobrepor isto com um puxador posterior, mas um limpo não o removerá, a menos que adicione -x.
 18
Author: Tierlieb, 2015-03-18 19:46:19
Eu próprio resolvi isto.
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 dá uma lista das suas alterações locais. Continue a modificar o ramo " tmp " até que seja aceitável e depois volte a juntar-se ao master com:

git checkout master && git merge tmp

Para a próxima vez, você provavelmente pode lidar com isso de uma forma mais limpa, procurando "git stash branch" embora stash é provável que lhe cause problemas nas primeiras tentativas, assim como fazer a primeira experiência em um projeto não-crítico...

 17
Author: Simon B., 2017-01-14 15:13:29
Tenho uma situação estranha que nem git clean Nem git reset funciona. Tenho de remover o ficheiro em conflito de git index usando o seguinte programa em cada ficheiro não rastreado:
git rm [file]
Então sou capaz de puxar muito bem.
 15
Author: Chen Zhang, 2017-12-05 04:35:20
Estes 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 estes comandos

git pull origin master
Eu tentei muito, mas finalmente consegui sucesso com estes comandos.
 13
Author: vishesh chandra, 2014-03-20 04:24:02

Apesar da pergunta original, as respostas de topo podem causar problemas para as pessoas que têm um problema semelhante, mas não querem perder seus arquivos locais. Por exemplo, veja os comentários de Al-Punk e crizCraig.

A seguinte versão compromete as suas alterações locais a uma ramificação temporária (tmp), verifica a ramificação original (que estou a assumir ser master) e junta as actualizações. Você poderia fazer isso com stash, mas eu descobri que é geralmente mais fácil simplesmente usar o branch / merge abordagem.

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 é origin master.

 12
Author: Snowcrash, 2015-03-18 19:43:07

Faz apenas

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

Para evitar todos os efeitos secundários indesejados, como apagar ficheiros ou directórios que queria manter, etc.

 12
Author: user2696128, 2017-01-14 15:48:47

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

git reset origin/master
 11
Author: , 2013-02-15 13:41:43
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!
 10
Author: ddmytrenko, 2018-09-05 16:52:42
Li todas as respostas, mas estava à procura de uma única ordem para fazer isto. Eis o que fiz. Adicionei um nome git .gitconfig
[alias]
      fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"

Execute o seu comando como

git fp origin master

Equivalente a

git fetch origin master
git reset --hard origin/master
 9
Author: Venkat Kotra, 2016-07-08 13:11:14

Requisitos:

    Rastreia as mudanças locais para que ninguém as perca.
  1. Faça com que o repositório local corresponda ao repositório de origem remota.

Solução:

  1. Esconder as alterações locais.
  2. Buscar com limpo do ficheiros e diretórios ignorando .gitignore e hard reset to origin .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
 9
Author: vezenkov, 2017-01-14 15:44:53