Git rebase: konflikty wciąż blokują postęp

120

Mam gałąź git (zwaną v4), która została utworzona z mastera dopiero wczoraj. Było kilka zmian do opanowania, które chcę wprowadzić do wersji 4. Tak więc w wersji 4 próbowałem wykonać rebase z mastera i jeden plik ciągle coś schrzanił: jednowierszowy plik tekstowy, który zawiera numer wersji. Ten plik to app/views/common/version.txt, który przed zmianą bazy zawiera następujący tekst:

v1.4-alpha-02

Oto co robię:

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

version.txtTeraz wygląda tak:

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

Więc porządkuję to i teraz wygląda to tak:

v1.4-alpha-02

a potem próbowałem kontynuować: najpierw próbuję zatwierdzić:

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

Nie ma szczęścia. Więc próbowałem dodać plik:

git add app/views/common/version.txt

Brak odpowiedzi. Chyba brak wiadomości to dobra wiadomość. Więc staram się kontynuować:

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

W tym momencie, po tym, jak się z tym obchodzę, uderzam głową o biurko.

Co tu się dzieje? Co ja robię źle? Czy ktoś może mnie wyprostować?

EDIT - dla unutbu

Zmieniłem plik zgodnie z sugestią i otrzymałem ten sam błąd:

> 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
źródło
10
dziękuję za zadanie tego pytania ... miałem dokładnie ten sam problem
Archan Mishra
6
byłoby miło, gdybyś potwierdził jakąś odpowiedź
holms
3
@MaxWilliams, myślę, że (podobnie jak ja) źle zinterpretowałeś radę @unutbu : 1) najpierw biegnij git rebase master i pozwól jej zawieść ; 2) następnie edytujesz version.txti ustawisz tak, jak powinien wyglądać w tym momencie, i zapisz edycję; 3) to ty git add .../version.txt; 4) to robisz git rebase --continue( nie „zatwierdzaj” )! Jeśli się rebase --continuepowiedzie, jest już zatwierdzony (nie ma takiej potrzeby git commit!) - więc pozostaje tylko git push(jeśli używasz zdalnego repozytorium). Mam nadzieję, że to pomoże, jeśli dobrze zrozumiałem :)- na zdrowie!
sdaau
@MaxWilliams, czy kiedykolwiek dostałeś odpowiedź na to: ruby-forum.com/topic/187288 (natychmiast usunę to po odpowiedzi, jeśli ktoś inny nie dotrze tam pierwszy !!)
atw

Odpowiedzi:

102

Napotkałem podobny problem z rebase. Mój problem był spowodowany tym, że jedno z moich zatwierdzeń zmieniło tylko plik, a podczas rozwiązywania odrzuciłem zmianę wprowadzoną w tym zatwierdzeniu. Udało mi się rozwiązać mój problem, pomijając odpowiednie zatwierdzenie ( git rebase --skip).

Możesz odtworzyć ten problem w repozytorium testowym. Najpierw utwórz repozytorium.

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

Następnie zatwierdź oryginalną zawartość 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

Utwórz v4gałąź i zmień zawartość 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(-)

Wróć do masteri zmień zawartość version.txttak, aby podczas rebase wystąpił konflikt.

$ 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(-)

Przełącz się z powrotem do v4gałęzi i spróbuj ponownie bazować. Nie udaje się z konflitowaniem version.txtzgodnie z planem.

$ 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

Konflikt rozwiązujemy, wybierając masterzawartość version.txt. Dodajemy plik i próbujemy kontynuować naszą 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".

To nie wyszło ! Zobaczmy, jakie zmiany gitwedług nas są w naszym repozytorium.

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

Ach, ach, nie ma zmiany. Jeśli przeczytałeś szczegółowo poprzedni komunikat o błędzie, gitpoinformował nas o tym i zalecił użycie git rebase --skip. Powiedział nam: „Jeśli nie ma już nic do przygotowania, są szanse, że coś innego już wprowadziło te same zmiany; możesz chcieć pominąć ten patch”. Więc po prostu pomijamy zatwierdzenie i rebase powiedzie się.

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

Słowo ostrzeżenia : należy pamiętać, że git rebase --skipcałkowicie usunie to zatwierdzenie, które gitpróbowało zmienić bazę. W naszym przypadku powinno to być w porządku, ponieważ gitnarzeka, że ​​jest to puste zatwierdzenie. Jeśli myślisz, że straciłeś zmiany po zakończeniu rebase, możesz użyć, git reflogaby uzyskać identyfikator zatwierdzenia swojego repozytorium przed rebase, i użyć, git reset --hardaby przywrócić swój magazyn z powrotem do tego stanu (jest to kolejna destrukcyjna operacja).

Sylvain Defresne
źródło
4
Dzięki za poświęcenie czasu na napisanie tego obszernego wyjaśnienia, Sylvain! To czyni sprawę jaśniejszą. Myślę, że zawsze denerwowałem się pominięciem łatki, ponieważ wydawało się, że praca może się zgubić: tj. Łatka obejmowała wszystkie pliki, których dotyczy rebase, a nie tylko ten z konfliktem. Czy zatem łatka jest tylko pojedynczym scaleniem w jednym pliku?
Max Williams
3
Nie, łatka zawiera wszystkie różnice we wszystkich plikach zmodyfikowanych w jednym zatwierdzeniu. Ale kiedy używasz git rebase --skip, pomijasz tylko jedno zatwierdzenie. Generalnie git statusprzed pominięciem zatwierdzenia, wydaje mi się, czy jestem w takiej sytuacji.
Sylvain Defresne
1
Chciałem tylko powtórzyć Maxowi podziękowanie za poświęcenie czasu na napisanie świetnego wyjaśnienia - w końcu rozumiem, dlaczego tak się dzieje. Ja też się już nie boję rebase --skip:).
Ben Dolman
1
Ostrzeżenie - jeśli wprowadzisz kilka zmian w jednym zatwierdzeniu, możesz stracić pracę wykonując git rebase --skip. Właśnie to zrobiłem
Chrissy H
@ChrissyH O ile nie wykonałeś git reflog purgelub git reflog deletenadal możesz odzyskać zmiany za pomocą git reflog. Spróbuj sprawdzić różne zmiany, do których się tam odwołujesz, jednym z nich powinien być stan twojego drzewa przed rozpoczęciem całości git rebase.
Sylvain Defresne,
23

Cytując tutaj: http://wholemeal.co.nz/node/9

Hę?!? Nie, nie zapomniałem użyć git add, zrobiłem to ... jak ... 2 sekundy temu!

Okazuje się, że ponieważ nie ma zmian od poprawki, git podejrzewa, że ​​coś poszło nie tak. Git oczekuje zastosowania poprawki, ale plik pozostał niezmieniony.

Komunikat o błędzie nie jest zbyt intuicyjny, ale zawiera odpowiedź. Musimy tylko powiedzieć rebase, aby pominął tę poprawkę. Nie jest również konieczne naprawianie znaczników konfliktów w pliku. Otrzymasz wersję pliku z gałęzi, na której się opierasz.

$ git rebase --skip
Bijou Trouvaille
źródło
Po tym, jak użyłem git connectetool i poprawiłem zmiany, a następnie dodałem je i zatwierdziłem, po prostu wpisałem <code> git rebase --skip </code>, podczas gdy „Obecnie nie ma w żadnej gałęzi”. I wszystko zostało naprawione. Dzięki!
geerlingguy
Właściwie myślę, że to połączenie ciągle działającego git connectetool, potem git rebase --continue, potem git connectetool itd. Ostatecznie naprawiło moją sytuację.
geerlingguy
6

Ten komunikat o błędzie jest wynikiem twojego git commit -a -m "merged". Jeśli po prostu naprawić plik, a następnie uruchomić git add <file>i git rebase --continuepowinno działać dobrze. git rebase --continueto próba wykonania zatwierdzenia, ale stwierdzenie, że nie ma żadnych oczekujących zmian do zatwierdzenia (ponieważ już je zatwierdziłeś).

twalberg
źródło
1
Wydaje się to o wiele bardziej rozsądne niż przeskakiwanie, przynajmniej w ogólnym przypadku. Dziwię się, że nie jest wymieniona jako najlepsza odpowiedź.
Emerald D.
1
@EmeraldD., Nie działa. Naprawienie pliku i uruchomienie git add <file>nie rozwiąże problemu. git rebase --continue nadal donosiNo changes - did you forget to use 'git add'?
Pacerier
6

Zmień plik app / views / common / version.txt na

v1.4-alpha-01

W tym momencie w rebase pamiętaj, że rozwiązujesz konflikty scalania, aby pokazać postęp gałęzi innej niż główna .

Tak więc w zmianie bazy z

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

do

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

konflikt, który rozwiązujesz, dotyczy tego, jak utworzyć A * w gałęzi tematu.

Więc po wykonaniu git rebase --abortpolecenia powinny być

git checkout topic
git rebase master
< make edits to resolve conflicts >
git add .
git rebase --continue
unutbu
źródło
3
Dzięki unutbu, próbowałem, ale bez powodzenia: zobacz OP dla nowej edycji. okrzyki
Max Williams
4

Zachowanie, które widzisz, nie jest tym, czego oczekiwałbym od typowego rebase z tym konfliktem. Rozważ użycie oddzielnej gałęzi, aby wykonać tę rebase (zwłaszcza jeśli zdalnie wypchnąłeś już zatwierdzenia, które przewijasz do przodu). Ponadto, git mergetoolmogą być pomocne w rozwiązywaniu konfliktów i pamiętając, aby wydać git add.

W tym minimalnym przykładzie rebase działa zgodnie z oczekiwaniami. Czy możesz podać przykład pokazujący zachowanie, które widzisz?

#!/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
źródło
4

Oto kilka pomysłów:

Adam Monsen
źródło