Wpadłem w konflikt scalania. Jak mogę przerwać scalanie?

2536

Użyłem git pulli miałem konflikt scalania:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Wiem, że druga wersja pliku jest dobra i że moja jest zła, więc wszystkie moje zmiany powinny zostać porzucone. W jaki sposób mogę to zrobić?

Gwyn Morfey
źródło
30
Zdaję sobie sprawę, że jest to bardzo stare pytanie, ale czy chcesz przerwać całe scalanie i pozostawić gałąź, którą scalasz, nie scaloną, czy po prostu zignorować ten jeden plik jako część większego scalenia, pozwalając, aby wszystkie pozostałe pliki zostały scalone jako normalna? Dla mnie twój tytuł implikuje to pierwsze, a twoje pytanie pyta o drugie. Odpowiedzi robią oba, bez wyjaśniania.
rjmunro
Mam podobny przypadek przy zatwierdzeniu, mówiąc, że automatyczne scalanie nie powiodło się; naprawić konflikty, a następnie zatwierdzić wynik:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana 30.04.16
4
Gwyn, przydatne może być wybranie tutaj akceptowanej odpowiedzi. Najlepiej wybrany jest nieco mniej bezpieczny niż niektóre z bardziej aktualnych rozwiązań, więc myślę, że pomogłoby to wyróżnić innych nad nim :)
Polubowne

Odpowiedzi:

2219

Ponieważ twoje pullnie powiodło się, to HEAD(nie HEAD^) jest ostatnim „poprawnym” zatwierdzeniem w twoim oddziale:

git reset --hard HEAD

Innym elementem, który chcesz, jest pozwolić, aby ich zmiany zastąpiły zmiany.

Starsze wersje git pozwoliły na użycie „ich” strategii scalania:

git pull --strategy=theirs remote_branch

Ale od tego czasu zostało to usunięte, jak wyjaśniono w tym komunikacie Junio ​​Hamano (opiekun Git). Jak wspomniano w linku , zamiast tego zrobiłbyś to:

git fetch origin
git reset --hard origin
Pat Notz
źródło
49
Zamiast twardego resetowania, możesz przenieść go na bardziej szczegółowy poziom, wykonując: git fetch origin -> git reset origin (soft reset, your changes are still present) -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin) Nigdy więcej nie używam git pull. Ponieważ w walce między moim najnowszym kodem a źródłem, pochodzenie zawsze powinno wygrywać, ja zawsze git fetchi git rebase origin. To sprawia, że ​​moje połączenia i konflikty są nieliczne i dalekie.
Kzqai
7
Zgadzam się. Lubię też najpierw pobrać, a następnie zbadać wcześniejsze zmiany ( git log ..@{upstream}lub git diff ..@{upstream}). Potem, podobnie jak ty, zmienię podstawy mojej pracy.
Pat Notz
162
Jak zauważono w nowszej odpowiedzi, od wersji 1.6.1 można używać polecenia „git reset --merge”
Matt Ball
5
Użyłem git merge -X theirs remote_branchzamiast git pull --strategy=theirs remote_branchjak theirswygląda opcjarecursive
mlt
14
git merge --abortjest zdecydowanie lepsza.
Daniel Cassidy
1956

Jeśli twoja wersja git to> = 1.6.1, możesz użyć git reset --merge.

Ponadto, jak wspomina @Michael Johnson, jeśli twoja wersja git to> = 1.7.4, możesz także użyć git merge --abort.

Jak zawsze upewnij się, że nie masz żadnych niezatwierdzonych zmian przed rozpoczęciem scalania.

Ze strony podręcznika git merge

git merge --abortodpowiada git reset --mergeczasowi MERGE_HEADobecności.

MERGE_HEAD jest obecny, gdy trwa scalanie.

Ponadto w odniesieniu do niezatwierdzonych zmian podczas rozpoczynania scalania:

Jeśli masz zmiany, których nie chcesz zatwierdzać przed rozpoczęciem scalania, tylko git stashje przed scaleniem i git stash poppo zakończeniu scalania lub przerwaniu.

Carl
źródło
3
Ciekawe - ale instrukcja mnie przeraża. Kiedy dokładnie należy użyć? Kiedy musisz określić opcjonalne <commit>? #GitMoment: -o
conny
1
Zazwyczaj używasz tego, gdy chcesz ponownie wykonać scalenie od samego początku. Nigdy nie musiałem sam określać opcjonalnego zatwierdzenia, więc domyślny (brak opcjonalnego <commit>) jest w porządku.
Carl
44
Chciałbym, żeby ta odpowiedź miała więcej głosów! W tym momencie wydaje się to najbardziej odpowiednie rozwiązanie w wielu przypadkach.
Jay Taylor,
1
Nawet przy nieoczekiwanych zmianach git był w stanie przywrócić stan przed scaleniem. Miły!
T3rm1
2
Czy to git merge --aborttylko synonim git reset --merge? Nazwa z pewnością ma większy sens, ale czy ma taką samą funkcjonalność?
Tikhon Jelvis
517
git merge --abort

Przerwij bieżący proces rozwiązywania konfliktów i spróbuj odtworzyć stan sprzed scalenia.

Jeśli w momencie rozpoczęcia scalania wystąpiły nieprzewidziane zmiany w drzewie roboczym, git merge --abortw niektórych przypadkach nie będzie można odtworzyć tych zmian. Dlatego zaleca się, aby zawsze zatwierdzać lub ukrywać zmiany przed uruchomieniem git merge.

git merge --abortodpowiada git reset --mergeczasowi MERGE_HEADobecności.

http://www.git-scm.com/docs/git-merge

ignis
źródło
16
Jest to dostępne od wersji git 1.7.7. Jest to alias dla git reset - zlew.
Michael Johnson
162

To takie proste.

git merge --abort

Sam Git pokazuje rozwiązanie, gdy masz tego typu problemy i uruchom polecenie git status.

git status

Mam nadzieję, że to pomoże ludziom.

Jagruttam Panchal
źródło
97

Myślę, git resetże potrzebujesz.

Uważaj, git revertco oznacza coś zupełnie innego niż, powiedzmy, svn revert- w Subversion przywrócenie odrzuci twoje (niezatwierdzone) zmiany, przywracając plik do bieżącej wersji z repozytorium, podczas gdy git revert„cofnie” zatwierdzenie.

git resetpowinien zrobić równowartość svn revert, czyli odrzucić niechciane zmiany.

David Precious
źródło
76

W tym konkretnym przypadku użycia tak naprawdę nie chcesz przerwać scalania, wystarczy rozwiązać konflikt w określony sposób.

Nie ma też szczególnej potrzeby resetowania i przeprowadzania łączenia z inną strategią. Konflikty zostały poprawnie podkreślone przez git, a wymóg akceptacji zmian pozostałych stron dotyczy tylko tego jednego pliku.

W przypadku nie połączonego pliku w konflikcie git udostępnia w indeksie wspólną podstawową, lokalną i zdalną wersję pliku. (To jest miejsce, z którego są odczytywane do użycia w 3-drożnym narzędziu różnicowym git mergetool.) Możesz użyć, git showaby je wyświetlić.

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

Najprostszym sposobem rozwiązania konfliktu przy użyciu dosłownie wersji zdalnej jest:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

Lub z git> = 1.6.1:

git checkout --theirs _widget.html.erb
CB Bailey
źródło
5
dzięki za podpowiedź. czy to jednak nie jest słabym interfejsem użytkownika git?
Peter
@Peter: Nie jestem przekonany. Pożądany wynik można osiągnąć za pomocą kilku podstawowych poleceń z prostymi opcjami. Jakie ulepszenia byś zaproponował?
CB Bailey,
10
Myślę, że git 1.6.1polecenie ma sens i jest dobre. Właśnie tego bym chciał. Myślę, że rozwiązanie wcześniejsze niż 1.6.1 jest nieeleganckie i wymaga wiedzy o innych częściach git, które powinny być oddzielone od procesu rozwiązywania scalania. Ale nowa wersja jest świetna!
Peter
67

Dla scenariusza podobnego zrobiłem git fetchi git pull, wtedy zrozumiałem, że nie było przed gałąź gałąź master, co spowodowało niepożądanych konfliktów.

git reset --merge 

To cofnęło się bez resetowania moich lokalnych zmian.

naamadheya
źródło
45

Komentarze sugerują, że git reset --mergejest to alias dla git merge --abort. Warto zauważyć, że git merge --abortjest to odpowiednik tylko git reset --mergebiorąc pod uwagę, że MERGE_HEADjest obecny. Można to odczytać w pomocy git dla polecenia scalania.

git merge --abort jest równoważny git reset --merge, gdy MERGE_HEAD jest obecny.

Po nieudanym scaleniu, gdy nie ma MERGE_HEAD, nieudanego scalenia można cofnąć git reset --merge, ale niekoniecznie za pomocą git merge --abort. Są nie tylko starą i nową składnią tego samego .

Osobiście uważam, że jest git reset --mergeznacznie bardziej wydajny w przypadku scenariuszy podobnych do opisanego i ogólnie nieudane scalenia.

Martin G.
źródło
2
co tutaj właściwie oznacza „nieudane scalenie”? Łączyć się z konfliktami czy coś innego? Lub przeformułuj: kiedy MERGE_HEAD jest nieobecny? Moje dalsze pytanie dotyczy lepszego użycia „git reset --merge”.
Ewoks
@Ewoks git stash applyspowodowało dla mnie konflikt scalania, ale git merge --abortnie pomogło mi git reset --merge.
nitzel,
27

Jeśli skończysz z konfliktem scalania i nie masz nic do zatwierdzenia, ale nadal wyświetlany jest błąd scalania. Po zastosowaniu wszystkich wymienionych poniżej poleceń,

git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin

Proszę usuń

.git \ index.lock

Plik [wytnij wklej do innej lokalizacji w przypadku odzyskiwania], a następnie wprowadź dowolne z poniższych poleceń w zależności od wybranej wersji.

git reset --hard HEAD
git reset --hard origin

Mam nadzieję, że to pomaga !!!

Nirav Mehta
źródło
19

Alternatywą, która zachowuje stan kopii roboczej jest:

git stash
git merge --abort
git stash pop

Generalnie odradzam to, ponieważ w rzeczywistości przypomina to scalanie w Subversion, ponieważ odrzuca relacje gałęzi w następnym zatwierdzeniu.

Alain O'Dea
źródło
Uznałem, że takie podejście jest przydatne, gdy przypadkowo połączyłem się z gałęzią git-svn, która nie radzi sobie z tym dobrze. Scalanie squasha lub wiśniowe typy są lepsze podczas pracy z gałęziami śledzenia git-svn. W efekcie moje rozwiązanie przekształca scalenie w scalenie squasha po fakcie.
Alain O'Dea,
Najlepsza odpowiedź na pytanie
Fouad Boukredine
18

Ponieważ Git 1.6.1.3 git checkoutbył w stanie dokonywać transakcji z dowolnej strony scalania:

git checkout --theirs _widget.html.erb
Alain O'Dea
źródło
3

Stwierdziłem, że dla mnie zadziałało (przywróć pojedynczy plik do stanu sprzed scalenia):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*
Malcolm Boekhoff
źródło
-5

Sourcetree

Ponieważ nie dokonujesz scalenia, po prostu dwukrotnie kliknij inny oddział (co oznacza, że ​​go kasujesz), a kiedy zostaniesz zapytany o odrzucenie wszystkich zmian, zgódź się :)

Kamil Kiełczewski
źródło