Git rebase: los conflictos siguen bloqueando el progreso

120

Tengo una rama de git (llamada v4), que se hizo desde el maestro ayer. Hubo un par de cambios para dominar, que quiero incluir en la v4. Entonces, en la v4, intenté hacer un rebase desde el maestro, y un archivo sigue arruinando las cosas: un archivo de texto de una línea, que contiene el número de versión. Este archivo es app/views/common/version.txt, que antes de rebasar contiene este texto:

v1.4-alpha-02

Esto es lo que estoy haciendo:

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

El version.txtahora se ve así:

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

Entonces, lo ordeno y se ve así ahora:

v1.4-alpha-02

y luego traté de continuar: al principio intento un compromiso:

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

No hubo suerte ahí. Entonces, estaba tratando de agregar el archivo:

git add app/views/common/version.txt

Ninguna respuesta. No tener noticias es una buena noticia, supongo. Entonces, trato de 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".

Es en este punto, después de dar vueltas y vueltas con esto, que me golpeo la cabeza contra el escritorio.

¿Que está pasando aqui? ¿Qué estoy haciendo mal? ¿Alguien puede aclararme?

EDITAR - para unutbu

Cambié el archivo como sugirió y obtengo el mismo error:

> 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
fuente
10
gracias por hacer esta pregunta ... estaba enfrentando exactamente el mismo problema
Archan Mishra
6
sería bueno si confirma alguna respuesta
holms
3
@MaxWilliams, creo que tú (como yo) has malinterpretado el consejo de @unutbu : 1) primero corres git rebase master y dejas que falle ; 2) luego edita version.txty lo hace como debería verse en ese punto, y guarda la edición; 3) entonces tú git add .../version.txt; 4) ¡Entonces lo haces git rebase --continue( no 'comprometes' )! Si rebase --continuetiene éxito aquí, ya está comprometido (¡no es necesario git commitaquí!), Por lo que todo lo que queda por hacer es git push(si usa un repositorio remoto). Espero que esto ayude, si lo hice bien :), ¡salud!
sdaau
@MaxWilliams, ¿Alguna vez una respuesta para esto: ruby-forum.com/topic/187288 (I eliminará rápidamente esto después de una respuesta si alguien no llegar primero !!)
ATW

Respuestas:

102

Encontré un problema similar con una rebase. Mi problema se debió a que una de mis confirmaciones solo cambió un archivo y, al resolverlo, descarté el cambio introducido en esta confirmación. Pude resolver mi problema omitiendo el correspondiente commit ( git rebase --skip).

Puede reproducir este problema en un repositorio de prueba. Primero cree el repositorio.

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

Luego confirme el contenido original de version.txten master.

$ 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

Crea la v4rama y cambia el contenido 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(-)

Regrese ay mastercambie el contenido de version.txtpara que haya un conflit durante el 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(-)

Vuelva a la v4rama e intente volver a establecer la base. Falla con un conflit version.txtcomo estaba planeado.

$ 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 el conflicto seleccionando el mastercontenido de version.txt. Agregamos el archivo e intentamos continuar con nuestro rebase.

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

Fracasa ! Veamos qué cambios gitcreemos que hay en nuestro repositorio.

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

Ah ah, no hay cambio. Si leíste en detalle el mensaje de error anterior, gitcomunícanoslo y recomendó su uso git rebase --skip. Nos dijo: "Si no queda nada por poner en escena, es probable que algo más ya haya introducido los mismos cambios; es posible que desee omitir este parche". Así que simplemente saltamos el compromiso y la rebase se realiza correctamente.

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

Advertencia : tenga en cuenta que git rebase --skipeliminará por completo la confirmación que gitintentó reajustar. En nuestro caso, esto debería estar bien ya que gitse queja de que es una confirmación vacía. Si cree que ha perdido los cambios una vez que se completa la rebase, puede usar git reflogpara obtener el ID de confirmación de su repositorio antes de la rebase, y usar git reset --hardpara que su depósito vuelva a ese estado (esta es otra operación destructiva).

Sylvain Defresne
fuente
4
¡Gracias por tomarte el tiempo de escribir esa larga explicación, Sylvain! Eso lo hace más claro. Creo que siempre estaba nervioso por saltarme un parche, ya que sentía que el trabajo podía perderse: es decir, que el parche involucraba todos los archivos afectados por la rebase, en lugar de solo el que tenía el conflicto. Entonces, ¿un parche es solo una combinación en un solo archivo?
Max Williams
3
No, un parche contiene toda la diferencia en todos los archivos modificados en una única confirmación. Pero cuando se usa git rebase --skip, solo se salta una única confirmación. Generalmente emito un git statusantes de saltarme un compromiso para ver si estoy en esta situación.
Sylvain Defresne
1
Solo quería hacerme eco de Max al decir gracias por tomarse el tiempo para escribir una gran explicación; finalmente entiendo por qué está sucediendo esto. Tampoco tengo más miedo de rebase --skip:).
Ben Dolman
1
Advertencia: si tiene varios cambios en una confirmación, puede perder trabajo al hacer git rebase --skip. Acabo de hacerlo
Chrissy H
@ChrissyH A menos que hayas hecho una git reflog purgeo git reflog deleteaún puedas recuperar tus cambios usando git reflog. Intente verificar las diferentes confirmaciones a las que se hace referencia allí, una de ellas debería ser el estado de su árbol antes de comenzar el todo git rebase.
Sylvain Defresne
23

Citando desde aquí: http://wholemeal.co.nz/node/9

¿¡¿Eh?!? No, no me olvidé de usar git add, lo hice ... como ... ¡hace 2 segundos!

Resulta que debido a que no hay cambios en el parche, git sospecha que algo salió mal. Git espera que se haya aplicado un parche, pero el archivo no ha cambiado.

El mensaje de error no es muy intuitivo, pero contiene la respuesta. Solo necesitamos decirle a Rebase que se salte este parche. Tampoco es necesario corregir los marcadores de conflicto en el archivo. Terminará con la versión del archivo de la rama en la que está reajustando.

$ git rebase --skip
Bijou Trouvaille
fuente
Después de usar git mergetool y corregir los cambios, luego los agregué y los comprometí, simplemente ingresé <code> git rebase --skip </code> mientras 'No actualmente en ninguna rama'. Y todo quedó arreglado. ¡Gracias!
geerlingguy
En realidad, creo que fue una combinación de ejecutar continuamente git mergetool, luego git rebase, continuar, luego git mergetool, etc. lo que finalmente solucionó mi situación.
geerlingguy
6

Ese mensaje de error es el resultado de su git commit -a -m "merged". Si solo arregla el archivo, ejecútelo git add <file>y git rebase --continuedebería funcionar bien. git rebase --continueestá tratando de hacer una confirmación, pero encuentra que no hay cambios pendientes para confirmar (porque ya los comprometió).

Twalberg
fuente
1
Esto parece mucho más razonable que hacer un salto, al menos en el caso general. Me sorprende que no aparezca como la mejor respuesta.
EsmeraldaD.
1
@EmeraldD., No funciona. Arreglar el archivo y ejecutarlo git add <file>no resolverá el problema. git rebase --continue todavía informaNo changes - did you forget to use 'git add'?
Pacerier
6

Cambie app / views / common / version.txt a

v1.4-alpha-01

En este punto del rebase, recuerde que está resolviendo conflictos de fusión para mostrar la progresión de la rama no maestra .

Entonces, al rebasar de

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

a

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

el conflicto que está resolviendo está en cómo crear A * en la rama del tema.

Entonces, después de hacerlo git rebase --abort, los comandos deben ser

git checkout topic
git rebase master
< make edits to resolve conflicts >
git add .
git rebase --continue
unutbu
fuente
3
Gracias unutbu, lo intenté pero no tuve suerte: ver OP para una nueva edición. aplausos
Max Williams
4

El comportamiento que está viendo no es el que esperaría de un rebase típico con solo este conflicto. Considere usar una rama separada para hacer este rebase (especialmente si ya ha enviado las confirmaciones de forma remota que está adelantando). Además, git mergetoolpuede ser útil para resolver conflictos y recordar emitir un git add.

En este ejemplo mínimo, la rebase funciona como se esperaba. ¿Puede dar un ejemplo que muestre el comportamiento que está viendo?

#!/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
fuente
4

Aquí tienes algunas ideas:

Adam Monsen
fuente