Git rebase: i conflitti continuano a bloccare i progressi


120

Ho un ramo git (chiamato v4), che è stato creato da master proprio ieri. C'erano un paio di modifiche da padroneggiare, che voglio inserire nella v4. Quindi, nella v4, ho provato a fare un rebase dal master, e un file continua a rovinare le cose: un file di testo di una riga, che contiene il numero di versione. Questo file è app/views/common/version.txt, che prima del rebase contiene questo testo:

v1.4-alpha-02

Ecco cosa sto facendo:

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

L' version.txtora assomiglia a questo:

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

Quindi, lo metto in ordine e ora sembra così:

v1.4-alpha-02

e poi ho provato ad andare avanti: prima provo un commit:

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

Nessuna fortuna lì. Quindi, stavo cercando di aggiungere il file:

git add app/views/common/version.txt

Nessuna risposta. Nessuna notizia è una buona notizia, immagino. Quindi, provo a continuare:

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

È a questo punto, dopo aver girato e rigirato con questo, che sbatto la testa dalla scrivania.

Cosa sta succedendo qui? Che cosa sto facendo di sbagliato? Qualcuno mi può mettere in chiaro?

EDIT - per unutbu

Ho modificato il file come suggerito e ricevo lo stesso errore:

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

10
grazie per aver posto questa domanda .. stavo affrontando lo stesso identico problema
Archan Mishra

6
sarebbe bello se confermassi una risposta
holms

3
@ MaxWilliams, penso che tu (come me) abbia interpretato male il consiglio di @unutbu : 1) prima corri git rebase master e lascia che fallisca ; 2) poi lo modifichi version.txte lo fai come dovrebbe apparire in quel punto, e salvi la modifica; 3) poi tu git add .../version.txt; 4) allora lo fai git rebase --continue( non 'commetti' )! Se ha rebase --continuesuccesso qui, è già stato eseguito il commit (non è necessario git commitqui!), Quindi tutto ciò che resta da fare è git push(se si utilizza un repository remoto). Spero che questo aiuti, se ho capito bene :)- saluti!
sdaau

@MaxWilliams, hai mai ricevuto una risposta per questo: ruby-forum.com/topic/187288 (lo cancellerò prontamente dopo una risposta se qualcun altro non arriva prima !!)
atw

Risposte:


102

Ho riscontrato un problema simile con un rebase. Il mio problema è stato causato perché uno dei miei commit ha modificato solo un file e, durante la risoluzione, ho scartato la modifica introdotta in questo commit. Sono stato in grado di risolvere il mio problema saltando il commit corrispondente ( git rebase --skip).

È possibile riprodurre questo problema in un repository di prova. Per prima cosa crea il repository.

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

Quindi salva il contenuto originale di 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

Crea il v4ramo e modifica il contenuto di 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(-)

Torna a mastere modifica il contenuto di in version.txtmodo che ci sarà un conflitto durante il 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(-)

Torna al v4branch e prova a rebase. Non riesce con un conflitto version.txtcome previsto.

$ 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

Risolviamo il conflitto selezionando il mastercontenuto di version.txt. Aggiungiamo il file e proviamo a continuare il nostro 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".

Fallisce! Vediamo quali cambiamenti gitpensiamo ci siano nel nostro repository.

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

Ah ah, non ci sono cambiamenti. Se hai letto in dettaglio il messaggio di errore precedente, gitinformaci di questo e consiglia di utilizzare git rebase --skip. Ci ha detto "Se non è rimasto nulla da mettere in scena, è probabile che qualcos'altro abbia già introdotto le stesse modifiche; potresti voler saltare questa patch". Quindi saltiamo il commit e il rebase ha esito positivo.

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

Parola di cautela : si prega di notare che git rebase --skipil commit che ha gittentato di eseguire il rebase verrà eliminato completamente. Nel nostro caso, questo dovrebbe andare bene poiché gitsi lamenta che questo è un commit vuoto. Se pensi di aver perso le modifiche una volta completato il rebase, puoi utilizzare git reflogper ottenere l'ID commit del tuo repository prima del rebase e utilizzare git reset --hardper riportare il tuo depot in quello stato (questa è un'altra operazione distruttiva).


4
Grazie per aver dedicato del tempo a scrivere quella lunga spiegazione Sylvain! Questo lo rende più chiaro. Penso di essere sempre stato solo nervoso all'idea di saltare una patch perché sentivo che il lavoro poteva andare perso: cioè che la patch coinvolgeva tutti i file interessati dal rebase, piuttosto che solo quello con il conflitto. Quindi una patch è solo una singola unione su un singolo file?
Max Williams

3
No, una patch contiene tutta la differenza su tutti i file modificati in un unico commit. Ma quando lo usi git rebase --skip, salti solo un singolo commit. Generalmente emetto un messaggio git statusprima di saltare un commit per vedere se mi trovo in questa situazione.
Sylvain Defresne

1
Volevo solo fare eco a Max nel dire grazie per aver dedicato del tempo a scrivere un'ottima spiegazione: finalmente capisco perché sta accadendo. Inoltre non ho più paura di rebase --skip:).
Ben Dolman

1
Attenzione: se hai più modifiche in un commit, potresti perdere il lavoro eseguendo git rebase --skip. L'ho appena fatto
Chrissy H

@ChrissyH A meno che tu non abbia fatto un git reflog purgeo git reflog delete, puoi comunque ripristinare le modifiche utilizzando git reflog. Prova a controllare i diversi commit a cui si fa riferimento lì, uno di loro dovrebbe essere lo stato del tuo albero prima di iniziare il tutto git rebase.
Sylvain Defresne

23

Citando da qui: http://wholemeal.co.nz/node/9

Eh?!? No, non ho dimenticato di usare git add, l'ho fatto ... tipo ... 2 secondi fa!

Si scopre che, poiché non ci sono modifiche dalla patch, git sospetta che qualcosa sia andato storto. Git si aspetta che sia stata applicata una patch, ma il file è rimasto invariato.

Il messaggio di errore non è molto intuitivo, ma contiene la risposta. Dobbiamo solo dire a rebase di saltare questa patch. Inoltre, non è necessario correggere gli indicatori di conflitto nel file. Ti ritroverai con la versione del file dal ramo su cui stai ribasando.

$ git rebase --skip

Dopo aver utilizzato git mergetool e corretto le modifiche, quindi aggiunto e eseguito il commit, ho semplicemente inserito <code> git rebase --skip </code> mentre "Attualmente non in nessun ramo". E tutto è stato risolto. Grazie!
geerlingguy

In realtà, penso che sia stata una combinazione di esecuzione continua di git mergetool, poi git rebase --continue, poi git mergetool, ecc. Che ha finalmente risolto la mia situazione.
geerlingguy

6

Quel messaggio di errore è il risultato del tuo git commit -a -m "merged". Se aggiusti il ​​file, esegui git add <file>e git rebase --continuedovrebbe funzionare bene. git rebase --continuesta tentando di eseguire un commit, ma sta scoprendo che non ci sono modifiche in sospeso per il commit (perché le hai già impegnate).


1
Questo sembra molto più ragionevole che saltare, almeno nel caso generale. Sono sorpreso che non sia indicata come la migliore risposta.
EmeraldD.

1
@EmeraldD., Non funziona. La correzione del file e l'esecuzione git add <file>non risolveranno il problema. riporta git rebase --continue ancoraNo changes - did you forget to use 'git add'?
Pacerier

6

Cambia app / views / common / version.txt in

v1.4-alpha-01

A questo punto del rebase, ricorda che stai risolvendo i conflitti di unione per mostrare la progressione del ramo non master .

Quindi, ribasando da

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

per

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

il conflitto che stai risolvendo è nel modo in cui creare A * sul ramo dell'argomento.

Quindi, dopo averlo fatto git rebase --abort, i comandi dovrebbero essere

git checkout topic
git rebase master
< make edits to resolve conflicts >
git add .
git rebase --continue

3
Grazie unutbu, l'ho provato ma senza fortuna: vedi OP per la nuova modifica. applausi
Max Williams

4

Il comportamento che stai vedendo non è quello che mi aspetterei da un tipico rebase con solo questo conflitto. Considera l'utilizzo di un ramo separato per eseguire questo rebase (soprattutto se hai già inviato i commit in remoto che stai avanzando rapidamente). Inoltre, git mergetoolpuò essere utile per risolvere i conflitti e ricordarsi di emettere un file git add.

In questo esempio minimo, il rebase funziona come previsto. Puoi fornire un esempio che mostri il comportamento che stai vedendo?

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

4

Ecco alcune idee:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.