Git Pull não é possível, arquivos não mesclados

90

Eu li todas as perguntas semelhantes sobre isso; parece que nenhum dos seguintes funcionou:

Delete offending files
git reset --hard HEAD
git stash
git pull

Quase todas as combinações, armazenando alterações e puxando do repositório, resultam em arquivos não mescláveis. Gostaria de descartar todas as alterações locais e apenas usar o remoto, mas não posso clonar novamente (limitações de largura de banda e uso de internet com o desenvolvedor tentando fazer isso). Como eu faço isso?

Apenas tentei:

git stash
git pull

Também não funcionou.

Mais informações

Há um commit local e o upstream também tem um commit. Tentei, git pull --rebasemas ainda não funciona bem ... Isso me dá erros - "sair por causa de um conflito não resolvido". Se eu fizer isso git stash, git reset --hard HEAD, git pull --rebase, recebo o erro "pull is not possible, unmerged changes ..."

Christian Stewart
fonte

Respostas:

202

Digamos que o remoto é origine o branch está master, e digamos que você já tenha feito mastercheck-out, pode tentar o seguinte:

git fetch origin
git reset --hard origin/master

Isso basicamente pega o branch atual e o aponta para o HEADbranch remoto.

AVISO : conforme declarado nos comentários, isso descartará as alterações locais e substituirá o que estiver na origem .

Ou você pode usar os comandos de encanamento para fazer essencialmente o mesmo:

git fetch <remote>
git update-ref refs/heads/<branch> $(git rev-parse <remote>/<branch>)
git reset --hard

EDIT: Eu gostaria de explicar brevemente por que isso funciona.

A .gitpasta pode conter os commits para qualquer número de repositórios. Como o hash de confirmação é na verdade um método de verificação para o conteúdo da confirmação, e não apenas um valor gerado aleatoriamente, ele é usado para combinar conjuntos de confirmação entre repositórios.

Um branch é apenas um ponteiro nomeado para um determinado hash. Aqui está um exemplo de conjunto:

$ find .git/refs -type f
.git/refs/tags/v3.8
.git/refs/heads/master
.git/refs/remotes/origin/HEAD
.git/refs/remotes/origin/master

Cada um desses arquivos contém um hash apontando para um commit:

$ cat .git/refs/remotes/origin/master
d895cb1af15c04c522a25c79cc429076987c089b

Todos eles são para o mecanismo de armazenamento git interno e funcionam independentemente do diretório de trabalho . Fazendo o seguinte:

git reset --hard origin/master

git irá apontar o branch atual com o mesmo valor hash para o qual origin / master aponta. Em seguida, ele altera à força o diretório de trabalho para corresponder à estrutura / conteúdo do arquivo naquele hash.

Para ver isso no trabalho, vá em frente e tente o seguinte:

git checkout -b test-branch
# see current commit and diff by the following
git show HEAD
# now point to another location
git reset --hard <remote>/<branch>
# see the changes again
git show HEAD
Trevor Norris
fonte
2
A partir da recente edição aprovada, adicionando o aviso massivo no início, apenas para apontar que já foi mencionado: "Então [git] altera à força o diretório de trabalho para corresponder à estrutura / conteúdo do arquivo naquele hash." Mas acho que isso não foi suficientemente explícito.
Trevor Norris
6

Resolvido, usando o seguinte conjunto de comandos:

git reset --hard
git pull --rebase
git rebase --skip
git pull

O truque é rebase as alterações ... Tivemos alguns problemas para rebasear um commit trivial, então simplesmente pulamos usando git rebase --skip (depois de copiar os arquivos).

Christian Stewart
fonte
3

Se acontecer de você ter esse problema depois de executar um git fetche o git não estiver permitindo que você execute git pullpor causa de um conflito de mesclagem ( arquivos modificados / não mesclados , e para deixá-lo mais frustrado, ele não mostrará nenhum marcador de conflito no já que ainda não foi fundido). Se você não deseja perder seu trabalho, faça o seguinte.

preparar o arquivo.

$ git add filename

em seguida, esconda as alterações locais.

$ git stash

puxar e atualizar seu diretório de trabalho

$ git pull

restaure seu arquivo local modificado (o git irá mesclar automaticamente se puder, caso contrário, resolvê-lo)

$ git stash pop

Espero que ajude.

Nimeshka Srimal
fonte
2

Existe uma solução, mesmo se você não quiser remover suas alterações locais. Basta corrigir os arquivos não mesclados (por git addou git remove). Então faça git pull.

Preeti A.
fonte
1

Supondo que você queira descartar quaisquer alterações que tenha, verifique primeiro a saída de git status. Para qualquer arquivo que diga "não mesclado" próximo a ele, execute git add <unmerged file>. Em seguida, faça o acompanhamento com git reset --hard. Isso eliminará quaisquer alterações locais, exceto para arquivos não rastreados.

Ryan Stewart
fonte
Oh, certo. Ele não pode dizer "não mesclado". Também pode dizer "ambos modificados" ou talvez uma ou duas outras coisas. Qual é a saída de git status?
Ryan Stewart
Depois de postar isso, estou dizendo ao membro da equipe para tentar git rebase --aborte de git pull --rebaseacordo com a sugestão do git
Christian Stewart
1

Eu fui resolvido com git remove o arquivo unmerged localmente.

$ git rm <the unmerged file name>
$ git reset --hard
$ git pull --rebase
$ git rebase --skip
$ git pull
Already up-to-date.

Quando eu envio git commit depois:

$ git commit . -m "my send commit"
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
Chetabahana
fonte
0

A resposta de Ryan Stewart estava quase lá. No caso em que você realmente não deseja excluir suas alterações locais, há um fluxo de trabalho que você pode usar para mesclar:

  • Corra git status. Ele lhe dará uma lista de arquivos não mesclados.
  • Una-os (manualmente, etc.)
  • Corre git commit

O Git fará o commit apenas dos merges em um novo commit. (No meu caso, adicionei arquivos adicionais no disco, que não foram incluídos naquele commit.)

O Git então considera a fusão bem-sucedida e permite que você siga em frente.

Nightblade9
fonte