Git rebase: conflitos continuam bloqueando o progresso

120

Eu tenho um ramo git (chamado v4), que foi feito do mestre ontem. Houve algumas mudanças para dominar, que eu quero entrar na v4. Então, na v4, tentei fazer uma nova redefinição do mestre, e um arquivo continua estragando tudo: um arquivo de texto de uma linha, que contém o número da versão. Este arquivo é app/views/common/version.txt, que antes da nova rebase contém este texto:

v1.4-alpha-02

Aqui está o que estou fazendo:

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: new version, new branch
error: patch failed: app/views/common/version.txt:1
error: app/views/common/version.txt: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging app/views/common/version.txt
CONFLICT (content): Merge conflict in app/views/common/version.txt
Failed to merge in the changes.
Patch failed at 0001 new version, new branch

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

O version.txtagora é assim:

<<<<<<< HEAD:app/views/common/version.txt
v1.4-alpha-02
=======
v1.4-alpha-01
>>>>>>> new version, new branch:app/views/common/version.txt

Então, eu arrumo e fica assim agora:

v1.4-alpha-02

e então eu tentei continuar: no começo eu tento um commit:

> git commit -a -m "merged"
# Not currently on any branch.
nothing to commit (working directory clean)

Sem sorte lá. Então, eu estava tentando adicionar o arquivo:

git add app/views/common/version.txt

Sem resposta. Nenhuma notícia é boa, eu acho. Então, eu tento continuar:

> git rebase --continue
Applying: new version, new branch
No changes - did you forget to use 'git add'?

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

É nesse ponto, depois de dar voltas e mais voltas com isso, que estou batendo com a cabeça na mesa.

O que está acontecendo aqui? O que estou fazendo de errado? Alguém pode me esclarecer?

EDIT - para unutbu

Alterei o arquivo conforme sugerido e recebi o mesmo erro:

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: new version, new branch
error: patch failed: app/views/common/version.txt:1
error: app/views/common/version.txt: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging app/views/common/version.txt
CONFLICT (content): Merge conflict in app/views/common/version.txt
Failed to merge in the changes.
Patch failed at 0001 new version, new branch

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
Max Williams
fonte
10
obrigado por fazer esta pergunta .. Eu estava enfrentando exatamente o mesmo problema
Archan Mishra
6
Seria bom se você confirmar alguma resposta
holms
3
@ MaxWilliams, acho que você (como eu) interpretou mal o conselho de @unutbu : 1) primeiro você corre git rebase master e deixa falhar ; 2) então você edita version.txte faz como deve parecer naquele ponto, e salva a edição; 3) então você git add .../version.txt; 4) então você faz git rebase --continue( não 'confirma' )! Se rebase --continuefor bem-sucedido aqui, ele já está confirmado (não é necessário git commitaqui!) - então, basta fazer isso git push(se você usar um repositório remoto). Espero que isso ajude, se eu entendi direito :)- saúde!
Sdaau
@MaxWilliams, você nunca obter uma resposta para isso: ruby-forum.com/topic/187288 (I prontamente apagar este depois de uma resposta se alguém não chegar lá primeiro !!)
ATW

Respostas:

102

Eu encontrei um problema semelhante com uma rebase. Meu problema foi causado porque um dos meus commit alterou apenas um arquivo e, ao resolver, descartei a alteração introduzida neste commit. Consegui resolver meu problema ignorando o commit ( git rebase --skip) correspondente .

Você pode reproduzir esse problema em um repositório de teste. Primeiro crie o repositório.

$ mkdir failing-merge
$ cd failing-merge
$ git init
Initialized empty Git repository in $HOME/failing-merge/.git/

Em seguida, confirme o conteúdo original do version.txtmaster.

$ echo v1.4-alpha-02 > version.txt
$ git add version.txt
$ git commit -m initial
[master (root-commit) 2eef0a5] initial
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 version.txt

Crie a v4ramificação e altere o conteúdo de version.txt.

$ git checkout -b v4
Switched to a new branch 'v4'
$ echo v1.4-alpha-03 > version.txt
$ git add version.txt
$ git commit -m v4
[v4 1ef8c9b] v4
 1 files changed, 1 insertions(+), 1 deletions(-)

Volte para mastere altere o conteúdo de, version.txtpara que haja um conflito durante o rebase.

$ git checkout master
Switched to branch 'master'
$ echo v1.4-alpha-04 > version.txt
$ git add version.txt
$ git commit -m master
[master 7313eb3] master
 1 files changed, 1 insertions(+), 1 deletions(-)

Volte para o v4ramo e tente fazer uma nova recuperação. Ele falha com um conflito version.txtcomo planejado.

$ git checkout v4
Switched to branch 'v4'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: v4
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging version.txt
CONFLICT (content): Merge conflict in version.txt
Recorded preimage for 'version.txt'
Failed to merge in the changes.
Patch failed at 0001 v4

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
$ cat version.txt
<<<<<<< HEAD
v1.4-alpha-04
=======
v1.4-alpha-03
>>>>>>> v4

Resolvemos o conflito selecionando o masterconteúdo de version.txt. Nós adicionamos o arquivo e tentamos continuar com nossa nova base.

$ echo v1.4-alpha-04 > version.txt
$ git add version.txt
$ git rebase --continue 
Applying: v4
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Falha ! Vamos ver o que as mudanças gitpensam que existem em nosso repositório.

$ git status
# Not currently on any branch.
nothing to commit (working directory clean)

Ah ah, não há mudança. Se você leu em detalhes a mensagem de erro anterior, gitnos informou e recomendou o uso git rebase --skip. Ele nos disse: "Se não sobrar nada para o palco, é provável que algo já tenha introduzido as mesmas mudanças; você pode pular esse patch". Então, pulamos o commit e a rebase com sucesso.

$ git rebase --skip
HEAD is now at 7313eb3 master

Palavra de cautela : Nota Por favor, que git rebase --skipvai cair completamente o commit que gittentou rebase. No nosso caso, isso deve ser bom, pois gitestá reclamando que este é um commit vazio. Se você acha que perdeu as alterações após a conclusão da git reflogrecuperação , pode usar para obter o ID de confirmação do seu repositório antes da git reset --hardrecuperação e usar para recuperar seu depósito nesse estado (esta é outra operação destrutiva).

Sylvain Defresne
fonte
4
Obrigado por dedicar um tempo para escrever essa longa explicação Sylvain! Isso torna mais claro. Eu acho que estava sempre nervoso de pular um patch, pois parecia que o trabalho poderia se perder: ou seja, que o patch envolvia todos os arquivos afetados pelo rebase, em vez de apenas aquele com o conflito. Um patch é apenas uma mesclagem única em um único arquivo?
Max Williams
3
Não, um patch contém toda a diferença em todos os arquivos modificados em uma única confirmação. Mas ao usar git rebase --skip, você pula apenas uma única confirmação. Geralmente, emito um git statusantes de pular um commit para ver se estou nessa situação.
1111 Sylvain Defresne
1
Eu só queria repetir Max ao dizer obrigado por dedicar um tempo para escrever uma ótima explicação - finalmente entendo por que isso está acontecendo. Eu também não tenho mais medo de rebase --skip:).
Ben Dolman
1
Aviso - se você tiver várias alterações em uma confirmação, poderá perder o trabalho executando o git rebase --skip. Acabei de fazer
Chrissy H
@ChrissyH A menos que você tenha feito uma git reflog purgeou git reflog deleteainda possa recuperar suas alterações usando git reflog. Tente fazer o checkout dos diferentes commit que são referenciados lá, um deles deve ser o estado da sua árvore antes de você iniciar o todo git rebase.
Sylvain Defresne
23

Citação a partir daqui: http://wholemeal.co.nz/node/9

Hã?!? Não, não esqueci de usar o git add, fiz isso ... tipo ... 2 segundos atrás!

Acontece que, como não há alterações no patch, o git suspeita que algo deu errado. O Git espera que um patch seja aplicado, mas o arquivo permaneceu inalterado.

A mensagem de erro não é muito intuitiva, mas contém a resposta. Nós só precisamos dizer ao rebase para pular este patch. Também não é necessário corrigir os marcadores de conflito no arquivo. Você terminará com a versão do arquivo da ramificação na qual está refazendo novamente.

$ git rebase --skip
Bijou Trouvaille
fonte
Depois de usar o git mergetool e corrigir as alterações, adicioná-las e enviá-las, simplesmente digitei <code> git rebase --skip </code> enquanto 'Atualmente não está em nenhum ramo'. E tudo foi consertado. Obrigado!
geerlingguy
Na verdade, acho que foi uma combinação de execução contínua do git mergetool, git rebase --continue, git mergetool etc. que finalmente consertou minha situação.
precisa saber é o seguinte
6

Essa mensagem de erro é resultado da sua git commit -a -m "merged". Se você apenas consertar o arquivo, execute git add <file>e git rebase --continue, deve funcionar bem. git rebase --continueestá tentando fazer uma confirmação, mas descobre que não há alterações pendentes para confirmar (porque você já as confirmou).

Twalberg
fonte
1
Isso parece muito mais razoável do que pular, pelo menos no caso geral. Estou surpreso que não esteja listado como a melhor resposta.
EmeraldD.
1
@ EmeraldD., Não funciona. Corrigir e executar o arquivo git add <file>não resolverá o problema. git rebase --continue ainda relatóriosNo changes - did you forget to use 'git add'?
Pacerier 16/10/2015
6

Altere app / views / common / version.txt para

v1.4-alpha-01

Neste ponto da rebase, lembre-se de que você está resolvendo conflitos de mesclagem para mostrar a progressão da ramificação não mestre .

Então, ao refazer a

      A---B---C topic
     /
D---E---F---G master

para

              A*--B*--C* topic
             /
D---E---F---G master

o conflito que você está resolvendo está em como criar A * na ramificação do tópico.

Então, depois de fazer git rebase --abort, os comandos devem ser

git checkout topic
git rebase master
< make edits to resolve conflicts >
git add .
git rebase --continue
unutbu
fonte
3
Obrigado unutbu, eu tentei isso, mas sem sorte: veja OP para nova edição. aplausos
Max Williams
4

O comportamento que você está vendo não é o que eu esperaria de uma recuperação típica com apenas esse conflito. Considere o uso de uma ramificação separada para fazer essa reformulação (especialmente se você já enviou os commit remotamente e está encaminhando rapidamente). Além disso, git mergetoolpode ser útil para resolver conflitos e lembrar-se de emitir a git add.

Neste exemplo mínimo, a rebase funciona conforme o esperado. Você pode fornecer um exemplo que mostra o comportamento que está vendo?

#!/bin/bash

cd /tmp
mkdir rebasetest
cd rebasetest
git init
echo 'v1.0' > version.txt
git add version.txt
git commit -m 'initial commit'
git checkout -b v4
echo 'v1.4-alpha-01' > version.txt
git add version.txt
git commit -m 'created v4'
git checkout master
git merge v4
echo 'v1.4-alpha-01-rc1' > version.txt
git add version.txt
git commit -m 'upped version on master to v1.4-alpha-01-rc1'
git checkout v4
echo 'v1.4-alpha-02' > version.txt
git add version.txt
git commit -m 'starting work on alpha-02'

git rebase master
echo 'v1.4-alpha-02' > version.txt
git add version.txt
git rebase --continue
Ben Taitelbaum
fonte
4

Aqui estão algumas idéias:

Adam Monsen
fonte