Git rebase: les conflits continuent de bloquer la progression

120

J'ai une branche git (appelée v4), qui a été créée à partir de master hier. Il y a eu quelques changements à maîtriser, que je veux entrer dans la v4. Donc, dans la v4, j'ai essayé de faire un rebase à partir de master, et un fichier n'arrête pas de bousiller les choses: un fichier texte d'une ligne, qui contient le numéro de version. Ce fichier est app/views/common/version.txt, qui avant le rebasage contient ce texte:

v1.4-alpha-02

Voici ce que je fais:

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

Le version.txtressemble maintenant à ceci:

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

Alors, je le range et ça ressemble à ceci maintenant:

v1.4-alpha-02

puis j'ai essayé de continuer: au début j'essaye un commit:

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

Pas de chance là-bas. Donc, j'essayais d'ajouter le fichier:

git add app/views/common/version.txt

Pas de réponse. Aucune nouvelle n'est une bonne nouvelle, je suppose. Alors, j'essaye de continuer:

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

C'est à ce stade, après avoir tourné en rond avec ça, que je me cogne la tête du bureau.

Que se passe t-il ici? Qu'est-ce que je fais mal? Quelqu'un peut-il me remettre en ordre?

EDIT - pour unutbu

J'ai changé le fichier comme vous l'avez suggéré et j'obtiens la même erreur:

> 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
la source
10
merci d'avoir posé cette question .. J'étais confronté au même problème
Archan Mishra
6
Ce serait bien si vous confirmiez une réponse
holms
3
@MaxWilliams, je pense que vous (comme moi) avez mal interprété le conseil de @unutbu : 1) commencez par courir git rebase master et laissez-le échouer ; 2) puis vous éditez version.txtet faites comme il devrait regarder à ce point, et enregistrez l'édition; 3) puis vous git add .../version.txt; 4) alors vous faites git rebase --continue( pas 'commit' )! S'il rebase --continueréussit ici, il est déjà validé (pas besoin git commitici!) - il ne reste donc plus qu'à git push(si vous utilisez un dépôt distant). J'espère que cela aide, si j'ai bien compris :)- bravo!
sdaau
@MaxWilliams, avez-vous déjà obtenu une réponse à cela: ruby-forum.com/topic/187288 (je supprimerai rapidement ceci après une réponse si quelqu'un d'autre n'y arrive pas en premier !!)
atw

Réponses:

102

J'ai rencontré un problème similaire avec un rebase. Mon problème a été causé car l'un de mes commit n'a changé qu'un fichier, et lors de la résolution, j'ai annulé le changement introduit dans ce commit. J'ai pu résoudre mon problème en sautant le commit correspondant ( git rebase --skip).

Vous pouvez reproduire ce problème dans un référentiel de test. Créez d'abord le référentiel.

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

Puis validez le contenu original de version.txtin 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

Créez la v4branche et modifiez le contenu 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(-)

Revenez à masteret modifiez le contenu de version.txtpour qu'il y ait un conflit pendant le 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(-)

Revenez à la v4branche et essayez de rebaser. Il échoue avec un conflit version.txtcomme prévu.

$ 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

Nous résolvons le conflit en sélectionnant le mastercontenu de version.txt. Nous ajoutons le fichier et essayons de continuer notre 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".

Il échoue ! Voyons quels changements gitpensent qu'il y a dans notre référentiel.

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

Ah ah, il n'y a pas de changement. Si vous avez lu en détail le message d'erreur précédent, gitnous en avons informé et recommandé l'utilisation git rebase --skip. Il nous a dit: "S'il ne reste plus rien à mettre en scène, il y a des chances que quelque chose d'autre ait déjà introduit les mêmes changements; vous voudrez peut-être sauter ce patch." Nous sautons donc simplement le commit et le rebase réussit.

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

Mise en garde : Note S'il vous plaît que git rebase --skipnous supprimons totalement commit qui a gitessayé de rebasage. Dans notre cas, cela devrait être correct car gitse plaindre qu'il s'agit d'un commit vide. Si vous pensez avoir perdu les modifications une fois le rebase terminé, vous pouvez utiliser git reflogpour obtenir l'ID de validation de votre référentiel avant le rebase, et l'utiliser git reset --hardpour remettre votre dépôt dans cet état (c'est une autre opération destructive).

Sylvain Defresne
la source
4
Merci d'avoir pris le temps d'écrire cette longue explication Sylvain! Cela rend les choses plus claires. Je pense que j'étais toujours juste inquiet de sauter un patch car j'avais l'impression que le travail pouvait être perdu: c'est-à-dire que le patch impliquait tous les fichiers affectés par le rebase, plutôt que celui avec le conflit. Un patch n'est-il donc qu'une seule fusion sur un seul fichier?
Max Williams
3
Non, un patch contient toute la différence sur tous les fichiers modifiés en un seul commit. Mais lors de l'utilisation git rebase --skip, vous ne sautez qu'un seul commit. J'émets généralement un git statusavant de sauter un commit pour voir si je suis dans cette situation.
Sylvain Defresne
1
Je voulais juste faire écho à Max pour lui dire merci d'avoir pris le temps d'écrire une bonne explication - je comprends enfin pourquoi cela se produit. Je n'ai plus peur de rebase --skip:).
Ben Dolman
1
Attention - si vous avez plusieurs changements dans un commit, vous risquez de perdre votre travail en exécutant git rebase --skip. Je viens de le faire
Chrissy H
@ChrissyH Sauf si vous avez fait une git reflog purgeou git reflog deletevous pouvez toujours récupérer vos modifications en utilisant git reflog. Essayez de récupérer les différents commit qui y sont référencés, l'un d'eux devrait être l'état de votre arbre avant de commencer le tout git rebase.
Sylvain Defresne
23

Citant d'ici: http://wholemeal.co.nz/node/9

Hein?!? Non, je n'ai pas oublié d'utiliser git add, je l'ai fait ... comme ... il y a 2 secondes!

Il s'avère que parce qu'il n'y a pas de changement par rapport au correctif, git soupçonne que quelque chose s'est mal passé. Git s'attend à ce qu'un correctif ait été appliqué, mais le fichier est resté inchangé.

Le message d'erreur n'est pas très intuitif, mais il contient la réponse. Nous avons juste besoin de dire à rebase de sauter ce patch. Il n'est pas non plus nécessaire de corriger les marqueurs de conflit dans le fichier. Vous obtiendrez la version du fichier de la branche sur laquelle vous rebasez.

$ git rebase --skip
Bijou Trouvaille
la source
Après avoir utilisé git mergetool et corrigé les modifications, puis les avoir ajoutées et validées, j'ai simplement entré <code> git rebase --skip </code> alors que 'Pas actuellement dans aucune branche.' Et tout était réparé. Merci!
geerlingguy
En fait, je pense que c'était une combinaison de git mergetool en cours d'exécution continue, puis de git rebase --continue, puis de git mergetool, etc. qui a finalement résolu ma situation.
geerlingguy
6

Ce message d'erreur est le résultat de votre git commit -a -m "merged". Si vous ne faites que réparer le fichier, exécutez git add <file>et git rebase --continue, cela devrait fonctionner correctement. git rebase --continueessaie de faire une validation, mais constate qu'il n'y a pas de modifications en attente à valider (car vous les avez déjà validées).

Twalberg
la source
1
Cela semble beaucoup plus raisonnable que de faire un saut, du moins dans le cas général. Je suis surpris que ce ne soit pas la meilleure réponse.
EmeraldD.
1
@EmeraldD., Ne fonctionne pas. La réparation du fichier et l'exécution git add <file>ne résoudront pas le problème. rapports git rebase --continue encoreNo changes - did you forget to use 'git add'?
Pacerier
6

Remplacez app / views / common / version.txt par

v1.4-alpha-01

À ce stade du rebase, rappelez-vous que vous résolvez les conflits de fusion pour montrer la progression de la branche non maître .

Donc, en rebasant de

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

à

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

le conflit que vous résolvez concerne la création de A * sur la branche thématique.

Donc, après avoir fait git rebase --abort, les commandes devraient être

git checkout topic
git rebase master
< make edits to resolve conflicts >
git add .
git rebase --continue
unutbu
la source
3
Merci unutbu, j'ai essayé mais pas de chance: voir OP pour une nouvelle modification. cheers
Max Williams
4

Le comportement que vous voyez n'est pas ce à quoi je m'attendrais d'un rebase typique avec juste ce conflit. Pensez à utiliser une branche distincte pour faire ce rebase (surtout si vous avez déjà poussé les commits à distance que vous avancez rapidement). En outre, git mergetoolpeut être utile pour résoudre les conflits et se souvenir d'émettre un fichier git add.

Dans cet exemple minimal, le rebase fonctionne comme prévu. Pouvez-vous donner un exemple qui montre le comportement que vous observez?

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

Voici quelques idées:

Adam Monsen
la source